Understanding UINavigationControllers

You should have read the Understanding UIKit tutorial before undertaking this one. We will be using the same project from that tutorial. At this point you should now have a application that has two tabs. Let’s add a second view to the first tab.

The first thing you should do is attempt to conceptualize how this might be done. Right now we understand a couple of things. UIViewControllers control UIViews, and this can be done by loading a nib file (which is easy) or creating a view programmatically (which is not so easy). UITabBarControllers control UIViewControllers. UIViewControllers don’t know anything at all about tabbing. And they shouldn’t. All the logic for tabbing between views is handled by UITabBarController.

So now consider moving smoothly from one view to the next as is often seen in iPhone apps.

UIViewControllers should have to know very, very little about this behavior. This means there is probably a class that encapsulates this behavior. This is where UINavigationController comes into the picture. UINavigationController handles the navigation back and forth between UIViewControllers. So logically, if we’re going to make the first tab have two views that you can move back and forth between, we need our UIViewControllers to be embedded into the UINavigationController.

First things first, let’s create the MyThirdViewController and MyThirdView.xib. You should be familiar with creating this by now. Try to figure out all the steps. The view should have a UILabel “Third View” in it.

Once you’re done with that open the MainWindow.xib file from the ViewControllersFun XCode project. Interface Builder will launch if it’s not already open. When you see the window for the MainWindow.xib, select the list view mode for the nib file. Open the Tab Bar Controller instance. You should see the list of embedded instances as we did in the last tutorial. We want to add a UINavigationController to be the view controller for the first tab.

This is easy. Open up the Library window and drag a UINavigationController into the Tab Bar Controller instance. Move the MyFirstViewController into your new UINavigationController. Your nib file should now look something like this:

view7

Note that when you double click on the Tab Bar Controller instance, the view looks quite different now. You now have a UINavigationBar at the top of the first tab view.

Let’s write some code. Switch back to XCode. Add the following method to the implementation of MyFirstViewController:

- (IBAction) showNextView:(id)sender
{
  NSLog(@"showNextView");
  // create an instance of MyThirdViewController and load the nib
  MyThirdViewController *nextView = [[MyThirdViewController alloc] initWithNibName:@"MyThirdView" bundle:nil];
  NSLog(@"navigationController %@", self.navigationController);
  [self.navigationController pushViewController:nextView animated:YES];
  // release the controller, navigationController has retained it
  [nextView release];
}

Here we are creating MyThirdViewController programmatically instead of using Interface Builder. There are several reason for this. Generally when you are using UINavigationController you are creating “temporary” views that the user will drill down into. These shouldn’t be very deep. In general, you only need the next level view for as long as the user is actually interested in it. When the user goes back to the previous view, the view that was drilled down to should be released.

That why we release the view after pushing it onto the navigation controller. The UINavigationController is now in charge of releasing the view. We are relinquishing responsibility.

Don’t forget that you need to include the header file for MyThirdViewController as well as add this method to the interface of MyFirstViewController if you don’t want to get compiler warnings. After you’ve done that, open up the MyFirstView.xib in Interface Builder. Add a UIButton below the UILabel and change the text to say “Next”. Right click on the new UIButton and drag from Touch Up Inside to File’s Owner and select the showNextView: action. Save your nib file. You should now be able to run your application from XCode.

Clearly several things are missing. The title of the navigation bar doesn’t reflect the view that you are looking at. You should look over View Controller Programming Guide for iPhone OS in Apple’s documentation for further details on how to customize UINavigationController and related classes.