views:

113

answers:

2

Trying to wrap my head around how to structure an app around the UINavigationController. It seems to me that most explanations assume that the app always starts off at the root controller and drills down from there, but I'm unclear as to how this fits in with a login/registration step that happens before you get into the app. The structure will be like this:

 Home page                                            | Main app (typical nav hierarchy)
------------                                          |---------------------------------
 Log in   ----> Login page                            | App section 1
               ------------                           | App section 2
                Do login   ------------------------>  | etc.
             <- Cancel                                |
                                                      |
 Register ------------------->  Register page         |
                               -----------------      |
                                Do registration --->  |
                             <- Cancel                |

So basically I'm assuming that the "Main app" controller should actually be the root controller of the application, correct? In which case I'm unclear on how to handle the whole process that sits in front of it (which is basically like a nav structure separate from the app nav structure). Is the "Home page" a modal controller displayed over the main app, and also a separate nav controller for the login/register steps, so that it simply gets popped after login to put us back at the app root?

Hopefully I'm just overcomplicating what is really a simple thing, just hasn't seemed to click for me yet. Any pointers greatly appreciated.

EDIT: So here's what I ended up with, which seems to work for what I need. I have two UINavigationControllers, both assigned to the MainWindow in IB with separate starting NIBs. One is the app startup nav controller (home/login/registration) and the other is the main app nav controller. My app delegate has this code:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [window addSubview:startNavController.view];
    [window makeKeyAndVisible];
    return YES;
}

- (void)activateMainApp {
    [startNavController.view removeFromSuperview];
    [window addSubview:appNavController.view];
    [window makeKeyAndVisible];
}

In the last step of login/registration, I have this code that is what calls the app delegate to make the switch between nav controllers:

- (IBAction)continuePressed {
    // Transfer control to the main app nav controller:
    MyAppDelegate *app = (MyAppDelegate*)[[UIApplication sharedApplication] delegate];
    [app activateMainApp];
    [app release];
}

I suspect that I could have accomplished this with one nav controller, but this made logical sense to me based on my view structure and seems to work, and I end up with the main home view as the app nav controller's root view, as desired. Any additional feedback is appreciated if there's something bone-headed about this.

A: 

UINavigationController is really just a way to organize UIViewControllers. There doesn't have to be a specific root view. You just put the views you want on top.

To add another view controller on top just call [UINavigationController pushViewController: animated:YES];

Conceited Code
+2  A: 

You can create a UINavigationController at any stage, including after your login screen - just make it a subview of the view you want to start using it on. You will see the view controller (which you made the root view of the new nav controller) at that point. Once you have it you can push new view controllers onto the navigation stack. You can look at the navigation stack

There is nothing really special about the root controller except that you can get there in one call (popToRootViewControllerAnimated) and that you can't pop further than that. All of the view controllers managed by the navigation controller are just on a stack so you can push onto the stack or pop off the stack as you like.

I think of it as a thing that is useful when the Back arrow will be useful.

Adam Eberbach
So are you saying that the login/registration steps would not actually be managed by a nav controller at all? The app delegate or a standard view controller would manage that part manually?
bmoeskau
Sure you could do it any number of ways. One way might be to create your login view in the visible part of the screen and then to animate in another view from an offscreen location to cover the login screen when login has been verified. The view that animates in houses your navigation controller. If someone hits the logout button you could slide it off again, clear the nav stack and start again.(it's like what an animation controller does I agree - but it sets root view "above" the login screen, and you might use some animated transition to distinguish it from ordinary in-app navigation.)
Adam Eberbach
Maybe this helps - you see views. A view sits in a View Controller, the nav controller moves the View Controllers. View Controllers can do a lot without one, they are a convenience object to slide one over the other and back again.Your view can be in the visible area or off-screen - it is fairly common to put the larger kind of controls like a UIDatePicker in the off-screen region until required, just as the system does with the keyboard. When you need it you bring it back to the visible part of the screen. You do the same with the nav controller view to commence stack-based navigation.
Adam Eberbach
I went ahead and accepted your answer as it did help me quite a bit in thinking through this. If you wouldn't mind checking out my edit and letting me know if you have any other feedback, I'd appreciate it. Thanks!
bmoeskau
Thanks for the accept - Looks like a reasonable scheme to me, it's not going to cause problems doing it that way as far as I can see. However you could have just one view controller and when you make the switch use setViewControllers: to replace the entire navigation stack with your new stack (and the new stack can be as simple as one controller in an array, becoming your new root controller - same effect as deallocating an old nav controller and swapping in a new nav controller).
Adam Eberbach
Good idea, I may try that approach -- seems like having one nav controller would feel more right. Thanks again for the feedback.
bmoeskau