DetailViewController only loading webpage on second time - ios

Ok, so I a a Master Detail application, and when a user clicks on a cell, it loads loads a webpage in the DetailViewController. The problem is, that on the iPhone version (this is a universal app) I have to click on the cell, then go back to the MasterViewController and then click on the cell again to load webpage. I only have to do this once, I think it is like initiating the webpage or something the first time. On the iPad version though, it loads it one the first time. So what's up?
Here is the code for my applicationDidFinishLaunching AppDelegate.m file, where I init the DetailViewController
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:#"MasterViewController_iPhone" bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
self.window.rootViewController = self.navigationController;
masterViewController.detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController_iPhone" bundle:nil];
} else {
MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:#"MasterViewController_iPad" bundle:nil];
UINavigationController *masterNavigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:#"DetailViewController_iPad" bundle:nil];
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
masterViewController.detailViewController = detailViewController;
self.splitViewController = [[UISplitViewController alloc] init];
self.splitViewController.delegate = detailViewController;
self.splitViewController.viewControllers = #[masterNavigationController, detailNavigationController];
self.window.rootViewController = self.splitViewController;
}
here is the code for the didSelectCellAtIndexPath
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *object = _objects[indexPath.row];
NSURL *ex = [NSURL URLWithString:[object objectForKey:#"url"]];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
self.detailViewController.detailItem = object;
[self.detailViewController loadURL:ex];
self.detailViewController.detailItem = object;
[self.detailViewController loadURL:ex];
[self.navigationController pushViewController:self.detailViewController animated:YES];
} else {
self.detailViewController.detailItem = object;
[self.detailViewController loadURL:ex];
}
}

On the iPad, you have the 2 controllers in a split view controller, so they are instantiated, and their view's loaded when the app starts up. On the iPhone, that second controller is instantiated, but it's view isn't loaded until you push it -- I think that's the difference. You should try moving the detailController method loadURL: to it's viewDidAppear method, instead of having it in the master controller's didSelectRowAtIndexPath method.

Related

Select row of UITableView and push ViewController according to row

I am using a custom control, SWRevealController for left-sliding menu like facebook. I have to ask user to sign in if he is not signed in and selects an option that require sign in.
I show an authentication view controller on clicking and user signs in. On success, I am supposed to push the view controller according to row selected before sign in.
I am using:
[self tableView:self.menuTable didSelectRowAtIndexPath:self.indexPath];
But it does not push the view controller on that row.
I have implemented delegate methods to get response whether user has sign in successfully or not, and I receive success.
Here is my tableView delegate method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SWRevealViewController *revealController = [self revealViewController];
UIViewController *frontViewController = revealController.frontViewController;
UINavigationController *frontNavigationController =nil;
self.indexPath = indexPath;
if ( [frontViewController isKindOfClass:[UINavigationController class]] )
frontNavigationController = (id)frontViewController;
NSInteger row = indexPath.row;
if(self.currentUser == nil){
SignInViewController *frontViewController = [[SignInViewController alloc] init];
frontViewController.delegate = self;
frontViewController.title = #"Cashmails";
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:frontViewController];
self.navController = navigationController;
[revealController pushFrontViewController:navigationController animated:YES];
}else{
CashmailViewController *frontViewController = [[CashmailViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:frontViewController];
[revealController pushFrontViewController:navigationController animated:YES];
}
}
Here is the delegate method I am using on getting success for sign in:
-(void) userSignInSuccessfully{
[self tableView:self.menuTable didSelectRowAtIndexPath:self.indexPath];
}
I have also tried this:
-(void) userSignInSuccessfully{
SWRevealViewController *revealController = [self revealViewController];
[revealController pushFrontViewController:self.navController animated:NO];
}
How I can achieve this, if I am using wrong approach.

Detailed view controller not showing from uilistview didSelect event

didSelectRowAtIndexPath: is firing but the view controller is not. I have tried different view controllers that I know are working. Since the method is firing then I can only speculate that
[self.navigationController pushViewController:detailVC animated:YES];
is not reaching the navigation stack.
But I call the Calendar View Controller from a tabbarcontroller so I do not know what to do to fix this.
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound)];
GlobalSingleton *myAppID = [GlobalSingleton sharedSingleton];
myAppID.globalAppID = #"627";
UIViewController *calendarVC;
calendarVC = [[[CalendarViewController alloc] initWithNibName:#"CalendarViewController" bundle:nil] autorelease];
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.viewControllers = #[calendarVC];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
self.tabBarController.customizableViewControllers = nil;
return YES;
}
CalendarViewController.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Row %#",[events objectAtIndex:indexPath.row] );
CalendarDetailVC *detailVC = [[CalendarDetailVC alloc] initWithNibName:#"CalendarDetailVC" bundle:nil];
detailVC.dictEvent = [events objectAtIndex:indexPath.row];
[self.navigationController pushViewController:detailVC animated:YES];
}
You don't have a navigation controller in your hierarchy, so you can't so a push. You need to add a line to create the navigation controller,
calendarVC = [[[CalendarViewController alloc] initWithNibName:#"CalendarViewController" bundle:nil] autorelease];
UINavigationController *nav = [[[UINavigationController alloc] initWithRootViewController: calendarVC] autorelease];
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.viewControllers = #[nav];

Using nibs and storyboards together

From what I have read on the internet, nibs and storyboards are comparable with each other in the same project. Now I am creating a tabbed application and would like to do the following:
Tab 1: constructed with nibs,
Tab 2: constructed with storyboards,
Tab 3: constructed with nibs
Initially I created everything with nibs so in my delegate I was passing from one tab to the next with this code:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
UIViewController *viewController1, *viewController2, *viewController3;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
viewController1 = [[[FirstViewController alloc] initWithNibName:#"FirstViewController_iPhone" bundle:nil] autorelease];
viewController2 = [[[SecondViewController alloc] initWithNibName:#"SecondViewController_iPhone" bundle:nil] autorelease];
viewController3 = [[[ThirdViewController alloc] initWithNibName:#"ThirdViewController_iPhone" bundle:nil] autorelease];
} else {
viewController1 = [[[FirstViewController alloc] initWithNibName:#"FirstViewController_iPad" bundle:nil] autorelease];
viewController2 = [[[SecondViewController alloc] initWithNibName:#"SecondViewController_iPad" bundle:nil] autorelease];
viewController3 = [[[ThirdViewController alloc] initWithNibName:#"ThirdViewController_iPad" bundle:nil] autorelease];
}
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.viewControllers = #[viewController1, viewController2, viewController3];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
Instead of having the SecondViewController_.xib I need to have the SecondViewController_.storyboard. How do I do this? Can I just change the name "SecondViewController_.nib" to "SecondViewController_.storyboard"? I don't think this would work..
Any help would be very appreciated!!
EDIT:
the code i was using :
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
self.title = NSLocalizedString(#"Events", #"Events");
self.tabBarItem.image = [UIImage imageNamed:#"second"];
}
return self; }
You could do what you're suggesting by creating a storyboard and then creating a SecondViewController scene inside it. In code, you would then replace initWithNibName: with calls to storyboardWithName: and instantiateViewControllerWithIdentifier:.
However, since a major feature in storyboards is the ability to tie multiple controllers together and define relationships between them, it's hard to imagine why doing it for one controller would be a good idea.
As Phillip said, just use instantiateViewControllerWithIdentifier.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
UIViewController *viewController1, *viewController2, *viewController3;
UIStoryboard *storyboard;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
viewController1 = [[[FirstViewController alloc] initWithNibName:#"FirstViewController_iPhone" bundle:nil] autorelease];
storyboard = [UIStoryboard storyboardWithName:#"iPhone" bundle:nil];
viewController2 = [storyboard instantiateViewControllerWithIdentifier:#"Second"];
viewController3 = [[[ThirdViewController alloc] initWithNibName:#"ThirdViewController_iPhone" bundle:nil] autorelease];
} else {
viewController1 = [[[FirstViewController alloc] initWithNibName:#"FirstViewController_iPad" bundle:nil] autorelease];
storyboard = [UIStoryboard storyboardWithName:#"iPad" bundle:nil];
viewController2 = [storyboard instantiateViewControllerWithIdentifier:#"Second"];
viewController3 = [[[ThirdViewController alloc] initWithNibName:#"ThirdViewController_iPad" bundle:nil] autorelease];
}
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.viewControllers = #[viewController1, viewController2, viewController3];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
This assumes that your storyboards were called iPhone.storyboard and iPad.storyboard, but change the above code to match whatever you call these two storyboards. Furthermore, this again assumes that you defined that scene to bear a "Storyboard ID" of Second (you do that by selecting the view controller in IB and going to the "Identity Inspector") and also that you specified your "custom class" there, too:
For SecondViewController, you should replace you initWithNibName:bundle: method with:
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
self.title = NSLocalizedString(#"Events", #"Events");
self.tabBarItem.image = [UIImage imageNamed:#"second"];
}
return self;
}

PushViewController with tabBarController not working

I have a tabBar application. One of the tabs has a rootviewcontroller that creates a UITableView and adds it to the subview. When a user clicks a cell in the UITableView I want to push a new rootviewcontroller but I cant get it to work.
In my appDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//Create the window
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
//Create the UIViewCOntrollers for each tab
_viewController1 = [[[LocavoreRetroFirstViewController alloc] initWithNibName:#"LocavoreRetroFirstViewController" bundle:nil] autorelease];
_viewController2 = [[[LocavoreRetroSecondViewController alloc] initWithNibName:#"LocavoreRetroSecondViewController" bundle:nil] autorelease];
UIViewController *viewController3 = [[[LocavoreRetroThirdViewController alloc] initWithNibName:#"LocavoreRetroThirdViewController" bundle:nil] autorelease];
_viewController4 = [[[LocavoreRetroFourthViewController alloc] initWithNibName:#"LocavoreRetroFourthViewController" bundle:nil] autorelease];
UIViewController *viewController5 = [[[LocavoreRetroFifthViewController alloc] initWithNibName:#"LocavoreRetroFifthViewController" bundle:nil] autorelease];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:_viewController1];
//[_viewController1 release];
NSArray* controllers = [NSArray arrayWithObjects:navigationController, _viewController2, viewController3, _viewController4, viewController5, nil];
//Create the tab controller
_tabBarController = [[[UITabBarController alloc] init] autorelease];
[_tabBarController setViewControllers:controllers];
//Initialize the tab controller with the views
// _tabBarController.viewControllers = #[_viewController1, _viewController2,
// viewController3, _viewController4, viewController5];
//Set the window to the tabcontroller view and make it visible
_window.rootViewController = _tabBarController;
_tabBarController.delegate=self;
[_window makeKeyAndVisible];
return YES;
}
In my subview didSelectRowAtIndexPath method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
RecipePageController *recipePageController = [[RecipePageController alloc] initWithNibName:#"RecipePageController" bundle:nil];
[self.navigationController pushViewController:recipePageController animated:YES];
[recipePageController release];
}
For each tab you need to create a separate navigation controller

Master detail uisplitViewController and UINavigationController view

I try to push from a detail view to an other view. I have a tableView in a detailView "ConRDPDetailViewController" and I will like that when I click on a row, that push the new view "BookmarkEditorController".
here is my method in "ConRDPDetailViewController" where I try to do that :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
ComputerBookmark* bookmark = nil;
if([indexPath section] == SECTION_BOOKMARKS)
{
// first row has either quick connect or add bookmark item
if([indexPath row] == 0)
{
// show add bookmark controller: is there I try to push the new View
BookmarkEditorController* bookmarkEditorController = [[[BookmarkEditorController alloc] initWithBookmark:[[ComputerBookmark alloc] initWithBaseDefaultParameters]] autorelease];
[bookmarkEditorController setTitle:NSLocalizedString(#"Ajouter Connexion", #"Add Connection title")];
UINavigationController *view = [[UINavigationController alloc] initWithRootViewController:bookmarkEditorController];
[view.navigationController pushViewController:bookmarkEditorController animated:YES];
[bookmarkEditorController setDelegate:self];
[bookmarkEditorController setHidesBottomBarWhenPushed:YES];
}
}
}
But nothing is happen, here is my method didFinishLaunchingWithOptions in AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self redirectConsoleLogToDocumentFolder];
// Initialize the app window
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
AuthentificationViewController *authentificationViewController =[[AuthentificationViewController alloc] initWithNibName:#"AuthentificationView" bundle:nil];
//self.window.rootViewController = self.splitViewController;
self.window.rootViewController = authentificationViewController;
[self.window makeKeyAndVisible];
// The new popover look for split views was added in iOS 5.1.
// This checks if the setting to enable it is available and
// sets it to YES if so.
// if ([self.splitViewController respondsToSelector:#selector(setPresentsWithGesture:)])
// [self.splitViewController setPresentsWithGesture:YES];
return YES;
}
Thank you in advance
You need to embed the table view controller in a navigation controller.
Then you can push the detail view with this code:
BookmarkEditorController* bookmarkEditorController = [[[BookmarkEditorController alloc] initWithBookmark:[[ComputerBookmark alloc] initWithBaseDefaultParameters]] autorelease];
[bookmarkEditorController setTitle:NSLocalizedString(#"Ajouter Connexion", #"Add Connection title")];
[self.navigationController pushViewController:bookmarkEditorController animated:YES];
[bookmarkEditorController setDelegate:self];
[bookmarkEditorController setHidesBottomBarWhenPushed:YES];

Resources