views:

41

answers:

2

I'm working on a navigation based app, and I chose it so that I can push and pop controllers on and off the stack. It's easy enough to move forward - just push a new controller. And moving back is easy as long as you go to the root view controller. There is a method called popToViewController:animated, but I didn't create the controller I want to pop to from within my current view controller, so the compiler complains that I haven't declared it. I know it's the second controller on the stack (one above the root). Can I use that to get there?

+1  A: 

The viewControllers property of a UINavigationController has the viewControllers in order that they were pushed, so you can use that and your knowledge of which view controller it is to pop to that view controller..here is a reference UINavigationController ref

Daniel
`[self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:NO];` got me back to the root + 1 controller. I read the docs on `popToViewController:animated`, but needed to go back to the `UINavigationController`. Thanks!
Steve
+1  A: 

I generally create a NavigationController object which has knowledge about both my UINavigationController and my viewControllers. If you give each of your VCs a reference to an object like this, or make it a singleton, then it can handle things like this for you.

There is nothing wrong with embedding navigation logic in view controllers, but it can make them harder to maintain when they know about every other view controller. Encapsulating navigation logic in a shared object makes your app easier to understand and maintain.

YMMV

logancautrell
+1 I like how that sounds, but I'm not sure how to implement it. I do have a singleton that I use to keep track of the current player, scores, etc. It also reads/writes data in .plists, like player names. Is your `NavigationController` object different than the `UINavigationController?` Do you create it when the app launches and then have it create all the view controllers? I'm new enough that I think I have an idea of how to do this, but I need a few more specifics...
Steve
What I like to do is hang it off the app delegate with a readonly property.Create a NavigationController class and give it a field for the UINavigationController. Add a constructor that takes a UINavigationController. In application:didFinishLaunchingWithOptions: create an instance of the NavigationController. Now instead of pushing/pop the navigation stack in your view controllers, create public methods on the NavigationController to handle this. This will allow you to remove interdependencies from your view controllers and separate your concerns more cleanly.
logancautrell
Another approach, which I've recently used on a large application, is to do navigation with notifications. In this case the navigation controller would subscribe to the notification center and listen for navigation events. When a user action required navigation, then the handling view controller would source a notification that described the navigation event. By doing this I was able to completely remove the navigation controller reference from everywhere except the app delegate. As an added bonus other objects could easily subscribe to the navigation events for setting up UI state.
logancautrell