- Developing with Navigation Controllers and Split Views
- Recipe: Building a Simple Two-Item Menu
- Recipe: Adding a Segmented Control
- Recipe: Navigating Between View Controllers
- Recipe: Presenting a Custom Modal Information View
- Recipe: Page View Controllers
- Recipe: Scrubbing Pages in a Page View Controller
- Recipe: Tab Bars
- Recipe: Remembering Tab State
- Recipe: Building Split View Controllers
- Recipe: Creating Universal Split View/Navigation Apps
- Recipe: Custom Containers and Segues
- One More Thing: Interface Builder and Tab Bar Controllers
- Summary
Recipe: Navigating Between View Controllers
In addition to providing menus, navigation controllers do the job they were designed to do: managing hierarchy as you navigate between views. Recipe 5-3 introduces the navigation controller as an actual navigation controller, pushing views on the stack.
The views in this recipe present a number, indicating how many view controllers have been pushed onto the stack. An instance variable stores the current depth number, which is used to both show the current level and decide whether to display a further push option. The maximum depth in this example is 6. In real use, you'd use more meaningful view controllers or contents. This example demonstrates things at their simplest level.
The navigation controller automatically creates the Level 2 back button shown in Figure 5-3 (left) as an effect of pushing the new Level 3 controller onto the stack. The rightmost button (Push) triggers navigation to the next controller by calling pushViewController:animated:. When pushed, the next back button reads Level 3, as shown in Figure 5-3 (right).
Figure 5-3 The navigation controller automatically creates properly labeled back buttons. After the Level 4 button is selected in the left interface, the navigation controller pushes the Level 4 view controller and creates the Level 3 back button in the right interface.
Back buttons pop the controller stack for you, releasing the current view controller as you move back to the previous one. Make sure your memory management allows that view controller to return all its memory upon being released. Beyond basic memory management, you do not need to program any popping behavior yourself. Note that back buttons are automatically created for pushed view controllers but not for the root controller itself, because it is not applicable.
Recipe 5-3. Drilling through Views with UINavigationController
#define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) @interface NumberViewController : UIViewController @property (nonatomic, assign) int number; @property (nonatomic, strong, readonly) UITextView *textView; + (id) controllerWithNumber: (int) number; @end @implementation NumberViewController @synthesize number, textView; // Return a new view controller at the specified level number + (id) controllerWithNumber: (int) number { NumberViewController *viewController = [[NumberViewController alloc] init]; viewController.number = number; viewController.textView.text = [NSString stringWithFormat:@"Level %d", number]; return viewController; } // Increment and push a controller onto the stack - (void) pushController: (id) sender { NumberViewController *nvc = [NumberViewController controllerWithNumber:number + 1]; [self.navigationController pushViewController:nvc animated:YES]; } // Set up the text and title as the view appears - (void) viewDidAppear: (BOOL) animated { self.navigationController.navigationBar.tintColor = COOKBOOK_PURPLE_COLOR; // match the title to the text view self.title = self.textView.text; self.textView.frame = self.view.frame; // Add a right bar button that pushes a new view if (number < 6) self.navigationItem.rightBarButtonItem = BARBUTTON(@"Push", )); } // Create the text view at initialization, not when the view loads - (id) init { if (!(self = [super init])) return self; textView = [[UITextView alloc] initWithFrame:CGRectZero]; textView.frame = [[UIScreen mainScreen] bounds]; textView.font = [UIFont fontWithName:@"Futura" size:IS_IPAD ? 192.0f : 96.0f]; textView.textAlignment = UITextAlignmentCenter; textView.editable = NO; textView.autoresizingMask = self.view.autoresizingMask; return self; } - (void) loadView { [super loadView]; [self.view addSubview:textView]; } - (void) dealloc { [textView removeFromSuperview]; textView = nil; } @end