Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

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() {         super.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() {         super.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.addTiles()         scene.swipeHandler = handleSwipe          gameOverPanel.hidden = true         shuffleButton.hidden = true          skView.presentScene(scene)          Sound.backgroundMusic.play()          beginGame()     }      func beginGame() {         displayTimeLabel.text = String(format: "%ld", stage.maximumTime)         score = 0         updateLabels()          stage.resetComboMultiplier()          scene.animateBeginGame() {             self.shuffleButton.hidden = false         }          shuffle()          startTiming()     }      func showWin() {         gameOverPanel.hidden = false         scene.userInteractionEnabled = false         shuffleButton.hidden = true          scene.animateGameOver() {             self.tapGestureRecognizer = UITapGestureRecognizer(target: self, action: "hideWin")             self.view.addGestureRecognizer(self.tapGestureRecognizer)         }     }      func hideWin() {         view.removeGestureRecognizer(tapGestureRecognizer)         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() {         super.viewDidLoad()     }      override func didReceiveMemoryWarning() {         super.didReceiveMemoryWarning()     }  } 
like image 994
codeinjuice Avatar asked Jun 22 '15 21:06

codeinjuice


People also ask

How do I dismiss a specific view controller in Swift?

Use unwind segue instead of using RootViewController. Using unwind you can go back to any ViewController. DismissViewController always send the controller out from NavigationController.

How do you dismiss the presenting view controller?

When it comes time to dismiss a presented view controller, the preferred approach is to let the presenting view controller dismiss it. In other words, whenever possible, the same view controller that presented the view controller should also take responsibility for dismissing it.


1 Answers

@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) 
like image 117
Phlippie Bosman Avatar answered Oct 13 '22 17:10

Phlippie Bosman