Add view to a navigation controller on app launch - iphone

I have an app that has a UITabBarController, one of the tabs of which is configured for a navigation controller.
Based on certain logic I need to attach a different root view to the navigation controller inside the tab at application launch time.
This is easily done in interface builder however, because I need to figure out what view to attach at launch time interface builder is not much use to me in this situation.
I'm guessing I will need to perform this in the applicationDidFinishLaunching method in my app delegate class by somehow getting the tab I'm interested in, and pushing the view onto it's navigation controller?
How would I go about this?
Thanks.

You're on the right track. In your app delegate's applicationDidFinishLaunching method, you need to look at whatever your condition is and pick the right thing to set as the UINavigationController's root view controller.
I'm guessing this is a login screen or something? And if you have a cached login from an earlier session you don't show it again? Is that it?
If you take a look at that method in your application delegate, you'll see where the default root view controller is getting instantiated and pushed into the nav controller. Just duplicate that code inside an if() statement. I've done this, it's straightforward.

So what I did in my applicationDidFinishLaunching method was:
// get the array of tabs
NSArray *tabBarArray = tabBarController.viewControllers;
// in my case the navigation controller I'm interested in is in the 4th tab
UINavigationController *navigationController = [tabBarArray objectAtIndex:4];
if(someLogic == true) {
ViewController1 *viewController1 = [[viewController1 alloc] initWithNibName:#"View1" bundle:nil];
[navigationController pushViewController:viewController1 animated:NO];
[viewController1 release];
}
else {
ViewController2 *viewController2 = [[viewController2 alloc] initWithNibName:#"View2" bundle:nil];
[navigationController pushViewController:viewController2 animated:NO];
[viewController2 release];
}
Everything working well.

Related

iPhone App - load View into Another View as soon as app has loaded

I have a rootviewcontroller and a loginviewcontroller. As soon as my app has finished loading up, I would like the rootviewcontroller to load the loginview associated with the loginviewcontroller. This is because the very first screen will be the user login.....
How is this possible?
The application flow should be as follows:
rootViewController -----immediately loads-----> loginviewcontroller -------user logs in--------> taken to mainmenuviewcontroller
The rootviewcontroller contains all the other controllers because it essentially holds global variables that store the results of processes carried out by other objects...
It depends on your overall UI architecture.
Without having much information, given the fact that it is a login view, I would push it as a modal view. Look at this document for more info.
In short, you can call presentModalViewController:animated: on your rootviewcontroller and pass it the loginviewcontroller. The login view controller will then be shown on top of the root view controller.
[rootViewController presentModalViewController:loginViewController animated:YES];
You should provide a way for your login view controller then to be dismissed and return control to the root view controller.
If u want to use first screen as login view and second one is root view controller then u use code as
- (void)applicationDidFinishLaunching:(UIApplication *)application {
viewController= [[loginViewController alloc] init];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:viewController];
[window addSubview:nc.view];
[window makeKeyAndVisible];
}
and then in loginViewController.m file call rootviewcontroller.

Showing a modal view controller from a tab bar app

First, I would like to warn that I am a complete newbie into iPhone coding...
I need to show up a viewcontroller from a library, I know that it is modal. I have a tab bar app (created with the default XCode template). I need to show that viewcontroller, there are no problem if it hides the tabbar itself... But I am quite clueless, I don't know even what to search, or what to read...
You can call presentModalViewController:animated: to display another UIViewController modally.
EDIT: If you want to display your modal view in response to a button touch (for example), you would display it like this:
- (IBAction)buttonTouched:(id)sender
{
ModalViewController* controller = [[ModalViewController alloc] init];
[self presentModalViewController:controller animated:YES];
[controller release];
}
Then when you want to dismiss the modal controller, call dismissModalViewControllerAnimated:. This can be called either on your main view controller, or the modal one.
I don't know even what to search, or
what to read...
View Controller Programming Guide is a good place to start to help you understand view controllers (including modal ones). If that's confusing, get a bigger picture with iOS Application Programming Guide or start at the very beginning.
You can call modal view as
YourViewController *yvc = [[YourViewController alloc] initWithNibName:#"YourViewController" bundle:YES]
[self presentModalViewController:yvc animated:YES];
You can call it in the IBAction method in case you want to call it on any control event like Button Click
-(IBAction)buttonClicked:(id)sender
{
YourViewController *yvc = [[YourViewController alloc] initWithNibName:#"YourViewController" bundle:YES]
[self presentModalViewController:yvc animated:YES];
}
You can call it using self.
Hope this helps you.
If you have more doubts on this then you can ask me.

How do you properly set up a secondary view to support a navigation Controller on the iPhone?

I have an iPhone app that shows a simple view (View 1) that has a button. When the user presses this button, View 2 slides into view using the call
[self presentModalViewController:self.view2 animated:YES];
I want View 2 to support a navigation controller. All the code I find tells you how to set up a Navigation Controller App, but I can't figure out how to set this up using IB.
What I have done is to create a plain view2.xib file. I set the file's owner class to view2.
I add a navigation Controller to the XIB. I create an IBOutlet called view2Nav in view2.h for a UINavigationController. I link view2Nav to the NavigationController in view2.xib.
I then create a view3 class with view3.xib. I set the RootViewController in view2.xib to be of class view3 and set its NIB name to view3.
Then I go back and run the program. When I press my button on view 1, the app crashes as it tries to create view 2.
I know I must be missing a setting or something.
MySecondViewController *secondVC = [[MySecondViewController alloc] initWithNibName:#"MySecondViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:secondVC];
[self presentModalViewController:navigationController animated:YES];
[secondVC release];
[navigationController release];
Forget about IB. Do anything in code :) It is faster and you will exactly know why and how it works.
I'm not sure whether you can pass a self.view2 to presentModalViewController. If self.view2 is a subclass of UIViewController, you can. If it is a simple UIView, you shouldn't. If fact you can't at all.

UITabBar and more than 1 UINavigationController

I'm currently working on an app that require that I have different UINavigationControllers - So I'm using a tab bar and attempting to use a UITabBar to swap between them so I have in the app delegate a bit of code like so:
// Setting up the views for the tab controller
Friends *friends = [[[Friends alloc] initWithNibName:#"Friends" bundle:[NSBundle mainBundle]] autorelease];
WifiManager *wifi = [[[WifiManager alloc] initWithNibName:#"WifiManager" bundle:[NSBundle mainBundle]] autorelease];
UINavigationController *locationController = [[UINavigationController alloc] initWithRootViewController:wifi];
UINavigationController *friendsController = [[UINavigationController alloc] initWithRootViewController:friends];
//Set up the tab controller
tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers =
[NSArray arrayWithObjects:locationController, friendsController, nil];
//Add the tab bar to the window
[window addSubview:tabBarController.view];
This will compile and will load up the first UINavigationController but when I click on the other navigation controller I get:
*** -[NSCFData tabBarItem]: unrecognized selector sent to instance 0x1152b0'
The strangest part is I can use the tab controller with a single UINavigationController and everything works as it should but when I try and add the second one it fails miserably - has anyone got any ideas as to what I'm doing so wrong here?
Thank you in advance
James
Have you verified that each of the single view controllers (Friends and WifiManager) work when there is only one? It could be that your problem is not "two controllers", but "one controller that is broken."
That code should work.
The only thing I can think to suggest, is to not autorelease the view controllers you are creating.
I have an application that works in a similar way. The way I handle this is to abstract it a little more. That is to say, let the top level (below the default window and stuff) be only the tab-bar controller. I would suggest deriving a custom class here so that you can get at the code. Then have each nav-bar controller reside within that tab-bar (within the nib-structure), but only worry about adding them when they are displayed.
Using Interface Builder: It was pretty simple to do with IB. In my MainWindow.xib file, the top level has all the normal stuff, Window, the generic UITabBarController and the UIViewControllers that I wish to push onto each UINavigationController, we'll say UIViewController 1b and 2b (1a and 2a are the two UIViewControllers that are the default views for each respective navbar). Nested within the UITabBarController, I have the UITabBar and my two UINavigationControllers. Within each, I have a UINavigationBar, a UIViewController, and a UITabBarItem, in that order. Here's what my code looks like in the app delegate:
[window addSubview:tabBarController.view];
[tabBarController setSelectedIndex:0];
Then when I want to make use of the navbars I do this:
UIViewController* newView = [[UIViewController alloc]initWithNibName:#"newViewController" bundle:nil];
[self.navigationController pushViewController:newView animated:TRUE];
[newView release];
That's all it takes for me to get it to work (I might have forgotten some IB wiring).
My final thought is that the bundle might be messing with your navbars. I have never used it and don't know much about the pros and cons, but you might try killing that to see if it's a fix, at least temporarily.

Navigation controller crashing on second time

I am using one navigation controller in my application. I am having one main view (with main view controller) and few options views. Options views are viewed by navigation controller when a button clicked on main view's toolbar.
Everything works as expected for first time. When I came back to main view from navigation controller and tries again to go to option view (i.e. navigation controller) my application crashes.
Following is my code,
//Jump to navigation controller from main view controller
optionsViewController *optionsView = [[optionsViewController alloc] initWithNibName:#"optionsView" bundle:nil];
navControllerSettings = [[UINavigationController alloc] initWithRootViewController:(UIViewController *) optionsView];
[self presentModalViewController:self.navControllerSettings animated:YES];
//Code to go back to main view from navigation controller
[self.navigationController dismissModalViewControllerAnimated:YES];
What is correct mechanism to handle navigation controller? Do I need to release/dealloc the navigation controller or options view?
Sample code will help better.
Your navigation controller only gets set up once, then you push and pop other views from its stack.
UINavigationController *navController = [[UINavigationController alloc] init];
UIViewController *yourMainViewController = [[yourMainViewControllerClass alloc] init];
// when you are ready to go to your options view
optionsViewController *optionsView = [[optionsViewController alloc] initWithNibName:#"optionsView" bundle:nil];
[navController pushViewController:optionsViewController animated:YES];
// the back button and the pop from the stack when it is hit is handled auto-magically for you
Thanks for the reply.
But my application architecture is, I am having one main view on which I display few things and having toolbar. Toolbar contains one button, after clicked on that this navigation controller gets created and displayed on the screen.
using back button I came on the main view. But then after I could not go on the navigation again as it is crashing while executing following line
[self presentModalViewController:self.navControllerSettings animated:YES];
What might be the problem here?
Vishal N
I had a similar problem to this with it crashing in presentModalViewController: on second attempt. The problem was caused by calling [self becomeFirstResponder] in viewDidAppear: inside the first UIViewController that I presented, but I failed to call [self resignFirstResponder] in viewWillDisappear:.