同时closures多个视图控制器

我正在使用SpriteKit进行游戏。 我有3个viewControllers:select级别VC,游戏VC,赢得VC。 游戏结束后,我想显示赢得VC,然后如果我按胜利VC上的确定button,我想解雇WIN VC和游戏VC(popup两个视图控制器出栈)。 但我不知道该怎么做,因为如果我打电话

self.dismissViewControllerAnimated(true, completion: {}) 

win vc(堆栈顶部)被解雇了,所以我不知道在哪里再打电话来解雇游戏vc。 有什么办法可以解决这个问题,而不使用导航控制器?

这是第一个VC:(请注意以下以“//”开头的评论)

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

这是第二个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() {...} } 

这是第三个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() } } 

@Ken Toh的评论是在这种情况下对我有用的 – 在视图控制器中放弃你想在所有其他东西被解散后显示的消息。

如果你有一个由3个视图控制器ABC构成的“栈”,其中C位于顶部,那么调用A.dismiss(animated: true, completion: nil)会同时closuresB和C.

如果您没有对堆栈根目录的引用,则可以将一些访问链接到presentingViewController来访问它。 像这样的东西:

 self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil) 

您可以在完成块中closuresWinVC的呈现控制器(GameViewController):

 let presentingViewController = self.presentingViewController self.dismissViewControllerAnimated(false, completion: { presentingViewController!.dismissViewControllerAnimated(true, completion: {}) }) 

或者,您可以联系到根视图控制器并调用dismissViewControllerAnimated,这将在一个animation中消除两个模式视图控制器:

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

你应该可以打电话给:

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

(您可能需要添加?!某处 – 我不是一个快速的开发人员)

有特殊的放松segue旨在将视图堆栈回滚到某个视图控制器。 请参阅我的答案在这里: 如何解雇2视图控制器在迅速的iOS?