iPhone Dev: Troubleshooting NavigationControllers in Interface Builder

In the simple example explained in this tutorial, and others, there are a few key points that I wish I’d seen in a blog somewhere, ha. It’s best to deal with literals, so I am recreating the example quickly, with notes on what aspects to check. If you have a complex or already created app, the first few steps will seem familiar. It seems to be an orchestration or sequence of references to IB objects and Xcode classes.

  1. Create a windows-based application for iPhone, for the sake of this example, I named it “test3”.
  2. Create a new File that is a View Controller, and give it a name (like RootViewController). SDK3.2 creates an appropriate XIB for you with the same name.
  3. Double-click MainWindow.xib in XCode to launch IB.
  4. In MainWindow, go Tools/Reveal in Document Window. Drag a UINavigationController object from the Library to the Document view, below “Window”.

  5. Open up the the Navigation Controller, expand View Controller. Access Tools/Inspector. Making sure View Controller is selected in the Document Window, view “Identity” and set class to your RootViewController class.
    Note: This associates the navigation controller in IB to the one you’ve created in your bundle.

  6. Click the Attributes tab and change the NamedNib to RootViewController.
    Note: this associates the navigation controller NIB in IB to the one in your app bundle.

  7. Also verify that, when Window in Document view is selected, the Inspector’s Connections tab shows that Window is pointing to [your app name]AppDelegate, for me it is “test3AppDelegate”.
    Note: this tells the app that when Window is loaded, access the Delegate to see instructions on what to load.

  8. Verify that: In Test3AppDelegate of Document view, check the Inspector /Connections, and confirm that window->Window, and delegate->File’s Owner.
    Note: This confirms that your class file’s instance variable “window” is properly mapped to XIB’s Window object.

  9. Now go back to XCode, we’re going to setup the NavController instance variable.
    1. Add the variable to the test3AppDelegate.h:

      @interface test3AppDelegate : NSObject {
      UIWindow *window;
      UINavigationController *navContr;

      @property (nonatomic, retain) IBOutlet UIWindow *window;
      @property (nonatomic, retain) IBOutlet UINavigationController *navContr;

    2. Add variable to .m

      @synthesize window;
      @synthesize navContr;

    3. While we’re here, let’s load the subview too, in “didFinishLaunchingWithOptions().”

      RootViewController *rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController" bundle:nil];
      [navContr pushViewController:rootViewController animated:NO];
      [rootViewController release];
      [window addSubview:navContr.view];
      [window makeKeyAndVisible];

    4. Remember to release the object:

      - (void)dealloc {
      [navContr release];
      [window release];
      [super dealloc];
  10. Back in IB, we have one last step: connect the Navigation Controller in MainWindow to the instance variable we just created. So click on Document View, select test3AppDelegate, and open Inspector/Connections tab. You should see your navigationController variable there – Now Control-drag it to the NavigationController in your Document View.

  11. Save, and run.