Dismiss more than one view controller simultaneously
Solution 1:
@Ken Toh's comment was what worked for me in this situation -- call dismiss from the view controller that you want to show after everything else is dismissed.
If you have a "stack" of 3 presented view controllers A
, B
and C
, where C
is on top, then calling A.dismiss(animated: true, completion: nil)
will dismiss B and C simultaneously.
If you don't have a reference to the root of the stack, you could chain a couple of accesses to presentingViewController
to get to it. Something like this:
self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil)
Solution 2:
You can dismiss WinVC's presenting controller (GameViewController) in the completion block:
let presentingViewController = self.presentingViewController
self.dismissViewControllerAnimated(false, completion: {
presentingViewController?.dismissViewControllerAnimated(true, completion: {})
})
Alternatively, you could reach out to the root view controller and call dismissViewControllerAnimated, which will dismiss both modal viewcontrollers in a single animation:
self.presentingViewController?.presentingViewController?.dismissViewControllerAnimated(true, completion: {})
Solution 3:
Swift 5 (and possibly 4, 3 etc)
presentingViewController?.presentingViewController?
is not very elegant and doesn't work in some instances. Instead, use segues
.
Let's say that we have ViewControllerA
, ViewControllerB
, and ViewControllerC
. We are at ViewControllerC
(we landed here through ViewControllerA
-> ViewControllerB
, so if we do dismiss
we will go back to ViewControllerB
). We want from ViewControllerC
to jump straight back to ViewControllerA
.
In ViewControllerA
add the following action in your ViewController class:
@IBAction func unwindToViewControllerA(segue: UIStoryboardSegue) {}
Yes, this line goes in the ViewController of the ViewController you want to go back to!
Now, you need to create an exit segue from the ViewControllerC
's storyboard (StoryboardC
). Go ahead and open StoryboardC
and select the storyboard. Hold CTRL down and drag to exit as follows:
You will be given a list of segues to choose from including the one we just created:
You should now have a segue, click on it:
Go in the inspector and set a unique id:
In the ViewControllerC
at the point where you want to dismiss and return back to ViewControllerA
, do the following (with the id we set in the inspector previously):
self.performSegue(withIdentifier: "yourIdHere", sender: self)
Solution 4:
You should be able to call:
self.presentingViewController.dismissViewControllerAnimated(true, completion: {});
(You may need to add ?
or !
somewhere - I'm not a swift developer)
Solution 5:
There's special unwind segue intended to roll back view stack to certain view controller. Please see my answer here: how to dismiss 2 view controller in swift ios?