AngryHacker
AngryHacker

Reputation: 61646

What is the pattern of navigating between UIViewControllers in iOS?

I have a bunch of UIViewControllers subclasses (let's call them MainForm, DetailForm, MoreMinorDetails). Basically the idea is that AppDelegate class instantiates MainForm, user presses some type of button on MainForm and DetailForm comes up. Then on a button on the DetailForm launches MoreMinorDetails. And of course, I should be able to go back down to the MainForm.

Note that there aren't any UINavigationController objects anywhere in sight.
What is the accepted pattern to move between UIViewControllers in a manner described above?

Or am I going about it in the wrong way? I'll be happy with either XCode or MonoTouch based explanation.

Upvotes: 1

Views: 334

Answers (2)

Lorenzo B
Lorenzo B

Reputation: 33428

AngryHacker,

My simple suggestion is to follow zoul one. I think the simplest way to achieve what you want it' to create a UINavigationController and use it as a containment controller for other controllers.

So, the way could be create a UINavigationController in the AppDelegate and set it as the rootViewController for your window. When you create a UINavigationController you can pass to it a root controller (in this case MainForm).

In MT it looks like the following (do not trust the code because I've written it by hand)

private UINavigationController navController;
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
    navController = new UINavigationController(new MainForm());
    window.RootViewController = navController;
    window.MakeKeyAndVisible ();

    return true;
}

Now, when you launch the app you will see the MainForm's view and will able to allow navigation among different controllers.

For example, within MainForm you can go to DetailForm like:

this.NavigationController.PushViewController(new DetailForm(), true);

The same applies within DetailForm to MoreMinorDetails.

To go one step back, for example from MoreMinorDetails to DetailForm use

this.NavigationController.PopViewControllerAnimated(false);

To go to the the root controller (MainForm) within DetailForm or MoreMinorDetails use

this.NavigationController.PopToRootViewControllerAnimated(false);

About the space, it's not a problem. I guess you have two ways. The first is to move the bar items you have created within the navigation controller bar. In each controller you can decide what buttons make visible or not. The second is to hide completely the navigation bar and use the button you've already created.

In both ways you can attach actions to these buttons and allow the navigation between controllers. Furthermore, if you choose the first you can also hide the back button for your navigation bar.

A simple note to take in mind is the following:

Since the navigation bar is unique for a UINavigationController, the bar will maintains its state for all the controllers you push in the navigation controller. To explain the concept suppose you have two controllers, say A and B. You first push A and in its ViewWillAppear method you hide a button. When you push B, the button still remains not visible. If you want to unhide the button in B, you can play with its ViewWillAppear method (like before) and so on...

If you don't want to play with UINavigationController you should take a look to new view controller containment functionality provided by UIViewController class. This applies only from iOS >= 5. You can obtain the same effect of UINavigationController mechanism but it could be more difficult to achieve.

Hope that helps.

Upvotes: 1

Andrei Filip
Andrei Filip

Reputation: 1153

You can use a UINavigationController and hide the navigation bar:

self.navigationController.navigationBar.hidden = YES;

Then in your button's action just push the next view controller:

-(void)buttonAction:(id)sender
{
    NextViewController *nextViewController = [[NextViewController alloc] init];
    [self.navigationController pushViewController:nextViewController animated:YES];
}

To go back, use

-(void)goBack
{
    [self.navigationController popViewControllerAnimated:YES];
}

To go to a certain view controller (you have to know exactly when it was pushed onto the navigation controller's stack):

-(void)goToViewController
{
    [self.navigationController popToViewController:[self.navigationController.viewControllers objectAtIndex:1] animated:YES];
}

Or to pop to your root view controller

[self.navigationController popToRootViewControllerAnimated:YES];

This way, you will obtain the UINavigationController's functionality and keep all the space in the view.

Upvotes: 2

Related Questions