Reputation: 1283
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
Reputation: 511716
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
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
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
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