My project is a view based project to start off.
So app delegate launches as per normal.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
Then my first viewcontroller is called and it shows two UITextFields so the user can enter their credentials and log on.
When that succeeds I call another view controller in which I add a UINavigationController and a UITabBarController to the view. As can be seen below.
- (void)viewDidLoad
{
[super viewDidLoad];
UINavigationController *localNavigationController;
tabBarController = [[UITabBarController alloc] init];
NSMutableArray *localControllersArray = [[NSMutableArray alloc] initWithCapacity:2];
Hello *firstViewController;
firstViewController = [[Hello alloc] init];
localNavigationController = [[UINavigationController alloc] initWithRootViewController:firstViewController];
[localNavigationController.tabBarItem initWithTitle:@"Test" image:[UIImage imageNamed:@"tabBarIcon.png"] tag:1];
//[localNavigationController.tabBarItem initWithTabBarSystemItem:UITabBarSystemItemDownloads tag:1];
firstViewController.navigationItem.title=@"New Requests";
[localControllersArray addObject:localNavigationController];
[localNavigationController release];
[firstViewController release];
Test *secondViewController;
secondViewController = [[Test alloc] init];
localNavigationController = [[UINavigationController alloc] initWithRootViewController:secondViewController];
[localNavigationController.tabBarItem initWithTitle:@"Test" image:[UIImage imageNamed:@"tabBarIcon.png"] tag:2];
secondViewController.navigationItem.title=@"Existing";
[localControllersArray addObject:localNavigationController];
[localNavigationController release];
[secondViewController release];
// load up our tab bar controller with the view controllers
tabBarController.viewControllers = localControllersArray;
// release the array because the tab bar controller now has it
[localControllersArray release];
// add the tabBarController as a subview in the window
[self.view addSubview:tabBarController.view];
}
This seems to work ok, so far. There was a problem off both the Navbar and Tabbar being dropped to low by the height of the status bar, but that was corrected once i hid the status bar.
Is there any reason I should not do things this way? Is it bad practice or will i run into some problems with it down the road?
I could set up both the Navbar and the Tabbar from the app delegate and just hide them both during the log-on screen. That’s the only other option I see.
I appreciate any feedback that you guys can offer. I feel nervous about the results of what I have done so far, expect it might blow up in my face.
Many Thanks,
-Code
You should generally not directly add the views of
UINavigationControllerandUITabBarControlleras subviews of your own view controllers. This kind of ‘view controller containment’ is tricky to get right unless you use the new iOS 5 APIs.The reason is that the actual view controllers will not receive certain important messages like
viewDidAppear:and rotation messages. You will notice strange rotation bugs and other weird issues cropping up. You can forward these methods yourself from the parent view controller and things will work OK, but in your case you have no need to do this because you’re just trying to show a standard tab bar controller.Generally you should have one view controller set up as the
UIWindow‘s root view controller. This is normally aUINavigationController,UITabBarController, etc. The parentUIWindowwill send rotation events and other messages to this controller. The standard ‘container’ controllers likeUITabBarControllerwill then forward these messages to their children so everything works correctly.If I were you, I would always have the tab bar controller as the window’s root view controller. When your app starts (i.e. in
application:didFinishLaunchingWithOptions:), create an empty tab bar controller and set it up as the root view controller:Now, whenever you present stuff on the screen, it should be a child of the root view controller, in your case the tab bar controller.
So once the root view controller is set up, you can check to see if the user is already logged in. If they are, you can then set up your navigation controller and the tab items, and add them to the tab bar controller.
If the user is not logged in, you can show your login view controller over the top of the tab bar controller using
presentModalViewController:animated::The
animated:NOwill cause the login screen to be immediately visible after starting the app with no animation.Once the user enters correct details you can again call your
setupTabsAndStuffmethod and dismiss the login view controller again.So to summarize:
presentModelViewController:animated