mpprdev
mpprdev

Reputation: 1283

IOS ViewController navigation path - how to navigate back programatically

I'm using IOS5 Storyboard. My View Controller path is as follows:

tabbarVC --> navigationVC-1 --> tableVC-1 --(via segue push)-> tableVC-2 --(via segue modal)-> navigationVC-2 --> tableVC-3

In the cancel button callback action method in tableVC-3 I call [self dismissViewControllerAnimated:YES completion:nil]; that successfully gets me back to tableVC-2. However when I try to examine the navigation path backwards in the debugger, I don't see a way to access tableVC-2 from navigationVC-2. I expected navigationVC-2 to maintain a link to tableVC-2 or navigationVC-1 but it doesn't seem to. Please see my debugger output below.

Can someone explain the navigation hierarchy and how to traverse the chain backwards programatically?

(gdb) po self
<tableVC-3: 0x6d33340>

(gdb) po (UIViewController*) [self navigationController]
<UINavigationController: 0x6d33560>

(gdb) po (UIViewController*)[[self navigationController] navigationController]
Can't print the description of a NIL object.

(gdb) po (UIViewController*)[[self navigationController] topViewController]
<tableVC-3: 0x6d33340>

(gdb) po (UIViewController*)[[self navigationController] presentingViewController]
<UITabBarController: 0x6b2eba0>

(gdb) po (UIViewController*)[[self navigationController] presentedViewController]
Can't print the description of a NIL object.

(gdb) po (UIViewController*)[[self navigationController] visibleViewController]
<tableVC-3: 0x6d33340>

Upvotes: 4

Views: 20697

Answers (4)

Suragch
Suragch

Reputation: 511716

Swift

If you are using a navigation controller the you can navigate back to the previous view controller with

self.navigationController?.popViewControllerAnimated(true)

or back to the root view controller with

self.navigationController?.popToRootViewControllerAnimated(true)

Upvotes: 0

Vincent Bernier
Vincent Bernier

Reputation: 8664

Going throw an old response tough of updating it to be more complet.
To address this question :

Can someone explain the navigation hierarchy and how to traverse the chain backwards programatically?

The structure of your navigation :

tabbarVC --> navigationVC-1 --> tableVC-1 --(via segue push)-> tableVC-2 --(via segue modal)-> navigationVC-2 --> tableVC-3

Can be explain like this :
The TabbarVC is showing it's 'selectedViewController' (navigationVC-1).
NavigationVC-1 has its navigation stack compose of TableVC-1 and TableVC-2 (topViewController of NavigagtionVC-1)
Then NavigationVC-2 is presented Modally over the tabbarVC, so tabbarVC is the presentingViewController and NavigationVC-2 is the presentedViewController

So in order to reach tableVC-2 from tableVC-3 you would need to do something like this :

[(UINavigationController *)[(UITabBarController *)[tableVC-3 presentingViewController] selectedViewController] topViewController];

(don't do that in production code)

[tableVC-3 presentingViewController] as well as [tableVC-3.navigationController presentingViewController] will give you back the UITabBarController.


If you are using a UINavigationController you should use it's push and pop method to put UIViewController on or off the "presentation stack".
You will be able to access the UINavigationController from those UIViewController like this:

self.navigationController

If you want to go back more than one UIViewController on the "presentation stack" you can use this method on the UINavigationController

popToViewController:animated:
Pops view controllers until the specified view controller is at the top of the navigation stack.
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated


To dismiss a UIViewController that was presented modally, the UIViewController that have presented it need to dismiss it with :

- (void)dismissModalViewControllerAnimated:(BOOL)animated

So in this case it should be :

[tableVC-2 dismissModalViewControllerAnimated:YES];

Upvotes: 4

Adam Knights
Adam Knights

Reputation: 2151

After some research using this and a couple other questions for modal UIViewControllers in storyboard to go back two views I used

[self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil];

Upvotes: 4

Mike Gledhill
Mike Gledhill

Reputation: 29161

This is an old question, but just to help anyone else who comes across this issue, there's a single command which'll make your life easier..

[self.navigationController popToRootViewControllerAnimated:TRUE];

Easy when you stumble across the right command, isn't it !

So, supposing you had a series of three screens in a Navigation Controller, and on the third screen you wanted the "Back" button to take you back to the initial screen.

-(void)viewDidLoad
{
    [super viewDidLoad];

    // change the back button and add an event handler
    self.navigationItem.leftBarButtonItem =
    [[UIBarButtonItem alloc] initWithTitle:@"Back"
                                     style:UIBarButtonItemStyleBordered
                                    target:self
                                    action:@selector(handleBack:)];
}


-(void)handleBack:(id)sender
{
    NSLog(@"About to go back to the first screen..");
    [self.navigationController popToRootViewControllerAnimated:TRUE];
}

Upvotes: 8

Related Questions