Dismiss more than one view controller simultaneously

I’m making a game using SpriteKit.
I have 3 viewControllers: selecting level vc, game vc, and win vc.
After the game is over, I want to show the win vc, then if I press OK button on the win vc, I want to dismiss the win vc AND the game vc (pop two view controllers out of the stack). But I don’t know how to do it because if I call

self.dismissViewControllerAnimated(true, completion: {})    

the win vc (top of the stack) is dismissed, so I don’t know where to call it again to dismiss the game vc.
Is there any way I can fix this without using navigation controller?

  • Passing data between views in ONE ViewController in Swift
  • Linking View Controllers through button
  • How to dismiss the current ViewController and go to another View in Swift
  • Access label.text from separate class in swift
  • iOS - Linking framework storyboard to ViewController for use in main project
  • Understanding View Controller Nesting in iOS
  • This is the 1st VC: (Please pay attention to my comments below starting with “//”)

    class SelectLevelViewController: UIViewController { // I implemented a UIButton on its storyboard, and its segue shows GameViewController
        override func viewDidLoad() {

    This is the 2nd VC:

    class GameViewController: UIViewController, UIPopoverPresentationControllerDelegate {
        var scene: GameScene!
        var stage: Stage!
        var startTime = NSTimeInterval()
        var timer = NSTimer()
        var seconds: Double = 0
        var timeStopped = false
        var score = 0
        @IBOutlet weak var targetLabel: UILabel!
        @IBOutlet var displayTimeLabel: UILabel!
        @IBOutlet weak var scoreLabel: UILabel!
        @IBOutlet weak var gameOverPanel: UIImageView!
        @IBOutlet weak var shuffleButton: UIButton!
        @IBOutlet weak var msNum: UILabel!
        var mapNum = Int()
        var stageNum = Int()
        var tapGestureRecognizer: UITapGestureRecognizer!
        override func viewDidLoad() {
            let skView = view as! SKView
            skView.multipleTouchEnabled = false
            scene = GameScene(size: skView.bounds.size)
            scene.scaleMode = .AspectFill
            msNum.text = "\(mapNum) - \(stageNum)"
            stage = Stage(filename: "Map_0_Stage_1")
            scene.stage = stage
            scene.swipeHandler = handleSwipe
            gameOverPanel.hidden = true
            shuffleButton.hidden = true
        func beginGame() {
            displayTimeLabel.text = String(format: "%ld", stage.maximumTime)
            score = 0
            scene.animateBeginGame() {
                self.shuffleButton.hidden = false
        func showWin() {
            gameOverPanel.hidden = false
            scene.userInteractionEnabled = false
            shuffleButton.hidden = true
            scene.animateGameOver() {
                self.tapGestureRecognizer = UITapGestureRecognizer(target: self, action: "hideWin")
        func hideWin() {
            tapGestureRecognizer = nil
            gameOverPanel.hidden = true
            scene.userInteractionEnabled = true
            self.performSegueWithIdentifier("win", sender: self) // this segue shows WinVC but idk where to dismiss this GameVC after WinVC gets dismissed...
        func shuffle() {...}
        func startTiming() {...}

    And this is the 3rd VC:

    class WinVC: UIViewController {
        @IBOutlet weak var awardResult: UILabel!
        @IBAction func dismissVC(sender: UIButton) {
            self.dismissViewControllerAnimated(true, completion: {}) // dismissing WinVC here when this button is clicked
        override func viewDidLoad() {
        override func didReceiveMemoryWarning() {

    4 Solutions Collect From Internet About “Dismiss more than one view controller simultaneously”

    @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)

    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: {})

    You should be able to call:

    self.presentingViewController.dismissViewControllerAnimated(true, completion: {});

    (You may need to add ? or ! somewhere – I’m not a swift developer)

    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?