Learn Objective-C, Building an App (Part 6): Navigation Controllers and Stacks

Navigation controllers are a cornerstone of iOS—they allow you to present a lot more information than you could fit on one screen, in a hierarchical format that is intuitive to the user. What does that mean? Think of it as a deck of cards (to use an oft-quoted metaphor). You have a stack of views with a “vertical” order. You can only see the top view, but there can be views underneath, and you can put views on top. And nav controllers are everywhere, so users are already familiar with it.

A UINavigationController handles the nav stack, as well as the corresponding animations. All you have to do is push and pop views controllers, if necessary. You will usually have to push view controllers on the stack, but by default, the back arrow in the upper-left will pop the controller automatically. You do have the ability to pop any number of existing view controllers programmatically if you need to—for example, in an app with a tab bar, tapping on a tab will take you to the root controller (first controller), which means that if you’re already in that tab, it’ll programmatically pop to the root controller.

Tab bar controllers and nav controllers are often seen together. In these situations you have some choices as to the design of the app. If each tab is displaying different content, you may want each tab to contain its own nav controller as the tab’s assigned view controller. Alternatively, if your different tabs just show a different sorting order or a different view on the same data, you might want to have the tab bar exist independently of the nav controller, and simply refresh the nav controller’s view when a different tab is selected. It is a bad idea to have each nav controller own its tab bar; you should not change your tab bar across different views of your app.

We’ll add navigation to our demo app, so open up the app that we’ve been working on not too long ago. Create a new UIViewController and call it CustomDrawingViewController (yes, next post we’ll look at doing some custom drawing using Quartz/Core Graphics—same thing). We’ll add a property that will allow you to set the title of the view before you push it on. Declare and synthesize a property of type NSString called viewTitle. Assign that property as the title in viewDidLoad:

  1. if (!self.viewTitle)
  2.         self.title = @"Custom Drawing";
  3.     else
  4.         self.title = self.viewTitle;

If the property did not get set, it’ll use the generic “Custom Drawing” title; otherwise it uses whatever was set. Now go to GraphicsTableViewController.m, where we’ll push the view controller. We do that in tableView:didSelectRowAtIndexPath:. Replace the deselect method with the following:

  1. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  2.     CustomDrawingViewController *drawingVC = [[CustomDrawingViewController alloc] init];
  3.     drawingVC.viewTitle = [[tableView cellForRowAtIndexPath:indexPath] textLabel].text;
  4.     [self.navigationController pushViewController:drawingVC animated:YES];
  5. }

Import CustomDrawingViewController.h. In this code, we create an instance of our new view controller. We set the title to be the text of the table view cell that was just tapped. Finally, we push on the new view controller. Note the call to self.navigationController. Nav controllers are so common in iOS that UIViewController contains a property to a parent navigation controller. If the view controller is not a child of a nav controller, then the property will be nil. Also note the animated parameter in the last method. You always want to animate the change if it’s going to be visible. Put another way, the only time you don’t want to animate is if you’re loading the first view of a stack, because the animation won’t be seen anyway.

Build and run, and select the Graphics Demo tab. Tap on any cell, and you’ll see an animation to a blank screen.

Pushing on a new view.

There will also be a back arrow in the upper left. Tap on that to go back.

Download the current version here.

This post is part of the Learn Objective-C in 24 Days course.

Author: Feifan Zhou