How to segue back to a UIViewController that's already loaded?

Go To StackoverFlow.com

47

I have a view on a storyboard the has a button to perform a certain action. To perform this action though, the user must be logged in. The button handler tests if the user is logged in and performs one segue if YES and another if NO. The NO segues pushes to a login view controller. There is another segue connecting back to the first view controller so if login is successfull the user can pick up where they left off. The view controllers are embedded in a navigation controller.

Problem is, the 'return' segue is loading a whole new instance of the view controller and not referencing the origional instance so I end up with empty interface elements and 2 copies of that view controller in memory.

How can I get back to the original instance of the view controller?

2012-04-04 00:58
by TijuanaKez


137

Assuming by your use of "push" you mean that you are using a UINavigationController, then you can use the following to return to the top of the stack.

[self.navigationController popToRootViewControllerAnimated:YES];

or

UIViewController *prevVC = [self.navigationController.viewControllers objectAtIndex:<n>];
[self.navigationController popToViewController:prevVC animated:YES];

to pop to a specific level where <n> is the level.

or

[self.navigationController popViewControllerAnimated:YES];

If you just want to pop one level back up the navigation stack.

2012-04-04 01:57
by Mick MacCallum
I have a UIBarButton that is initially loaded in ViewDidLoad in the previous screen (the one we're going back to). When I use your code, UIBar doesn't show at all. Any idea why - c1pherB1t 2012-05-01 15:52


33

Instead of using a segue to go back to the previous controller you should use the event that was associated with the segue going back to instead dismiss the current view controller (if segue was modal) or pop this from the navigation controller (if the segue was push) and the previous controller will show automatically.

For example, if the modal segue that goes back was being performed when you pressed a button on your login screen, you delete the segue from the storyboard and on the touch up inside event of the button you link with your action that, upon successful login will call:

 [self dismissViewControllerAnimated:YES completion:nil];

On the storyboard, you will right click on the button and drag the touch up inside sent event to the first responder of the view controller scene. This will execute the reverse transition that was executed when you performed the segue transition. You can use a modal segue for that, no need to use a navigation controller.

If you pushed the login view onto the navigation controller, then you have to pop it from the stack (if going back to the previous view). Use one of these:

    [[self navigationController] popViewControllerAnimated:YES];  // goes back to previous view
[[self navigationController] popToViewController: myViewControllerAfterLogin animated:YES]; // goes back to specific view on stack. 
[[self navigationController] popToRootViewControllerAnimated:YES]; // goes back to first view on the stack

The animated transition should reverse the type of transition used on the segue, so curl up will be curled down when you dismiss the view.

2013-05-20 21:07
by TRVD1707
If you're using a custom segue, such as a non slide effect for a push segue, the pop will not be the reverse of your custom segue, but rather just a slide effect - nenchev 2014-07-14 21:57


5

If you are using a segue to go forward then you should use an unwind segue to go back. Detailed info on how to use an unwind segue is in this Technical Note TN2298 Using Unwind Segues.

2015-04-19 16:11
by malhal


2

malhal is right - it's worth clicking on his link.

The code has seems to have moved on a little from Apple's example and is even more flexible. I have three scenes but only one custom ViewController .m file. I did not want a navigation stack. Access to the subsequent scenes is by segues from buttons. I added this line in the base view controller .m file:

- (IBAction)unwindForSegue:(UIStoryboardSegue *)unwindSegue towardsViewController:(UIViewController *)subsequentVC{}

Then in the third scene I control-dragged from a button to the exit icon and selected the unwind action. It now drops back from scene 3 back to scene 2 without needing to call a dismissViewController method.

2016-06-01 12:24
by Tim
I think the key thing that I finally understood was that it will unwind your stack until it gets to a controller that implements the unwindAction associated with the specific exit segue you are using. So you can define multiple exit segues with different unwind actions, and then you implement the specific unwind action in the controller where you want to land, for each of the segues - Andy Weinstein 2016-06-19 13:52