views:

404

answers:

1

Here's what I have:

  • A MainWindow.xib file configured with one UIViewController (subclassed to RootViewController). This nib gets loaded at application launch.

  • RootViewController has two ivars, a custom subclass of UIViewController and a UINavigationController. Both of these are loaded from nibs.

When the application launches both ivars are initialized from their respective nibs, and then the UIViewController.view is added as a subview of RootViewController.view.

Inside UIViewController's view I have a control that triggers an animated swap of UIViewController and UINavigationController. This is where the problem comes in. The swap animates, but the UINavigationController's views are not properly displayed. I get a Navigation Bar with no title, and nothing else.

The UINavigationController nib and underlying functionality have been tested in a stand alone project, but there was no RootViewController.

So, my question is, can I even do this? I've successfully swapped other view controllers like this, but never a UINavigationController. I've seen some documentation that leads me to believe this might be a fools errand, but I haven't convinced myself of that yet.

Solution (Kinda):

I found a solution (workaround? hack?), but it leads to some more questions. I nixed using a Nib for the UINavigationController. Instead, I loaded my UINavigationController's rootViewController from a Nib and then created the UINavigationController programmatically with initWithRootViewController:.

  NavRootViewController *navRoot = [[NavRootViewController alloc] initWithNibName:@"NavRootViewController" bundle:nil];
  navigationController = [[UINavigationController alloc] initWithRootViewController:navRoot];
  [navRoot release];

This works as I expect. Which leads me to the conclusion that the rootViewController property of the UINavigationController wasn't being set properly when I loaded navigationController from a Nib. And the question is, why? Should it?

A: 

I think you may have missed a conceptual point.

A UINavigationController controls view controllers instead of views. It controls when and where view controllers themselves are loaded. The views themselves are loaded only as a side effect of the pushing and popping of their respective controllers.

Therefore, putting a navigation controller inside of a view controller seldom makes much sense.

If I understand what you are trying to do correctly, you should have the RootController actually set as the rootController property of the UINavigationController (yes the nomenclature is extremely confusing.) Then when your swap event occurs, you should have the navigation controller push the next view. The RootController view will disappear to replaced by the other. then you can repeat the process for an arbitrary number of view controllers.

Only in the case of a tabbar would you want a navigation controller to be a property of a view controller. Even then it should be at the top the tab's hierarchy.

TechZen
Thanks for the answer. Making the UINavigationController the top View Controller was my Plan B. I really wanted to understand why this wasn't working. I have it working now, and will post additional info in my question because I still don't understand some things. I think Plan B will actually become Plan A once I make sure I can handle a few things.
Rob Jones
You definitely want you design to flow with the API instead of fighting it. That way lays heart ache, I know.
TechZen
You missed the point though. Sometimes you don't want a UINavigationController to be your root. In the project I'm working on currently I really do want two UIViewControllers that I can swap between and have each load their own nav controller. What you're suggesting is that one shouldn't do this, not an actual solution.
Ben Lachman
Well, yes and no. In almost all cases you want a hierarchal controller managing all the view controller in the app. For example, you have a tabbar with a separate nav controller in each bar. Those nav controllers are down inside the tabbar's hierarchy. Ditto for simply swapping views. Ideally, there should be a nav controller or a similar controller (custom or not) that manages which view controller/view pair is displayed and how to navigate to other views.
TechZen