How to present a second ViewController & dismiss the first
Asked Answered
S

5

9

using the following code in the parent ViewController, I want to present a second view ontop of the first, then dismiss the first:

// Animates the next questionViewController using the first questionViewController
[previousView presentViewController:nextQuestionViewController animated:YES completion:nil];

// Dismiss the first questionViewController
[previousView dismissViewControllerAnimated:NO completion:nil];

When run, the second view is presented, but the first view will not dismiss.

Sunflower answered 7/3, 2012 at 12:43 Comment(5)
previousView is a viewController on a navigation controller stack or it was displayed modally?Sweettalk
Yes, it is displayed modally. I can't figure out why it won't dismiss.Sunflower
From your code, it says only presentViewController:animated, not presentModalViewController:animatedSweettalk
From your code, it says only presentViewController:animated:completion:, not presentModalViewController:animated:. Check the Modal word in the middle of the message. Unless, presentViewController is a custom method, in that case, we would need more code.Sweettalk
From your code, it says only presentViewController:animated:completion:, not presentModalViewController:animated:. Check the Modal word in the middle of the message. Unless, presentViewController is a custom method, in that case, we would need more code.Sweettalk
A
12

You would need to first dismiss the "previousView" & then present the "nextQuestionViewController":

// Dismiss the first questionViewController
[previousView dismissViewControllerAnimated:NO completion:nil];

// Animates the next questionViewController using the first questionViewController
[previousView presentViewController:nextQuestionViewController animated:YES completion:nil];
Antechoir answered 8/5, 2012 at 11:53 Comment(2)
Following this answer results in the following exception: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller <FirstViewController: 0x71cf520>.'Gander
Don't you think it will be error prone to use a view controller to present another one knowing that it itself going to be deallocated at some point in time. I would rather use [[UIApplication sharedApplication].keyWindow.rootViewController or similar to present nextQuestionViewController, as suggested by @Mozilla.East
M
5

try

[self dismissViewControllerAnimated:NO completion:nil];

failing that:

[self.navigationController popViewControllerAnimated:YES];
Montymonument answered 7/3, 2012 at 12:57 Comment(2)
I'm attempting to solve this issue again - using both of those methods fails to dismiss the second viewController, after presenting the first - am I missing something else?Sunflower
As Raphael says, you should present the second viewController as follows: [previousView presentModalViewController: nextQuestionViewController animated:YES];Montymonument
J
2

I did next (self - is your old controller):

UIStoryboard *storyboard = self.storyboard;

[self dismissViewControllerAnimated:YES
                         completion:^{
        UIViewController *newController = [storyboard instantiateViewControllerWithIdentifier:@"newControllerStoryboardId"];
        newController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;

        [[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:newController animated:YES completion:nil];
    }];
Jun answered 19/12, 2013 at 12:14 Comment(0)
C
0

It might be better to use an "unwind segue":

https://developer.apple.com/library/archive/featuredarticles/ViewControllerPGforiPhoneOS/UsingSegues.html#//apple_ref/doc/uid/TP40007457-CH15-SW8

https://developer.apple.com/library/archive/technotes/tn2298/_index.html

It allows you to dismiss multiple view controllers at the same time, without having to know how many there are in the stack. And without the presented view controller having special knowledge of where it needs to navigate back to (i.e. you don't have to reach out directly to the window's root view controller).

Let's say you have some root view controller called VC1, the first modal is VC2, and the second modal is VC3.

In VC1 you would implement an IBAction called (for instance) unwindToRoot. Then in the storyboard for VC3, you wire up your Done button to the Exit object and choose the unwindToRoot action.

When that button is pressed, the system will dismiss all the view controllers it needs to bring you back to VC1.

So basically you are just letting all these VC stack up, and when you are all done you are dismissing everything to return to the root VC.

Centralia answered 11/1, 2019 at 16:43 Comment(0)
P
-2

It seems that it is not possible to go from B to C without showing A briefly, which looks unprofessional. However, you can put a black subview over top of A until you've animated to C.

For code, see my answer at https://mcmap.net/q/1172928/-how-to-dismiss-own-view-controller-and-present-another-view-controller-in-a-button-tap

Pellitory answered 8/8, 2017 at 23:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.