IOS ViewController navigation path - how to navigate back programatically
Solution 1
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];
}
Solution 2
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];
Solution 3
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];
mpprdev
Updated on June 10, 2020Comments
-
mpprdev about 4 years
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>
-
mpprdev over 12 yearsActually my question is different. Notice that I have 2 navigation controllers in play. My question is how to get back to the first navigation controller. If you see the debug output I pasted, there doesn't seem to be any way to traverse back to the first navigation controller.
-
mpprdev over 12 yearsthanks for the comments. Without the 2nd nav controller, the 'modal' type segue doesn't seem to work (app crashes).
-
Vincent Bernier over 12 years@mpprdev - Ok I get it, I'm less use to segue. You don't want to go back you want to dismiss your modal presentation.
-
Jason Rogers about 12 yearsNot linked to the question but thanks, I've been looking for the pop function for a while but hadn't found the navigation controller (was looking in parent controller... Now it all makes cense
-
pAkY88 over 11 yearsA little remark: if you want to go back to the previous view, without passing it as parameter, you can just use the following code: [[self navigationController] popViewControllerAnimated:YES];
-
joker over 9 yearsThe comment made me try
[self.navigationController.navigationController popToRootViewControllerAnimated:YES];
. The structure was like: Navigation Controller -> TableView -> (via push segue) -> Navigation Controller -> View Controller. This worked with me! Moreover, it gave me insight of how things work.