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.

Tim Windsor Brown
  • 4,069
  • 5
  • 25
  • 33
  • previousView is a viewController on a navigation controller stack or it was displayed modally? – Raphael Ayres Mar 07 '12 at 13:25
  • Yes, it is displayed modally. I can't figure out why it won't dismiss. – Tim Windsor Brown Mar 19 '12 at 13:42
  • From your code, it says only presentViewController:animated, not presentModalViewController:animated – Raphael Ayres Mar 19 '12 at 13:58
  • 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. – Raphael Ayres Mar 19 '12 at 14:00
  • 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. – Raphael Ayres Mar 19 '12 at 14:10

5 Answers5

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];
Bern11
  • 255
  • 3
  • 12
  • 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 .'` – Jade Nov 21 '12 at 05:19
  • 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. – atulkhatri Mar 21 '16 at 09:53
5

try

[self dismissViewControllerAnimated:NO completion:nil];

failing that:

[self.navigationController popViewControllerAnimated:YES];
ader
  • 5,403
  • 1
  • 21
  • 26
  • 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? – Tim Windsor Brown Aug 20 '12 at 16:16
  • As Raphael says, you should present the second viewController as follows: [previousView presentModalViewController: nextQuestionViewController animated:YES]; – ader Aug 28 '12 at 08:53
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];
    }];
Serge Maslyakov
  • 1,410
  • 1
  • 17
  • 23
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.

Nate Petersen
  • 888
  • 8
  • 11
-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://stackoverflow.com/a/45579371/218226

prewett
  • 1,587
  • 14
  • 19