如何在dismiss当前ViewController的同时执行Segue跳转至其他视图控制器
问题根因
你当前的写法存在两个核心问题:
dismiss(animated:completion:)是异步执行方法,调用后不会立刻销毁当前视图控制器,你紧接着调用的performSegue执行时,系统已经标记当前控制器要被移除,不会响应跳转请求- 即使等dismiss执行完成,当前控制器已经被移出视图层级,不再持有页面跳转能力,所有视图相关方法都会失效,严重时会触发野指针崩溃
解决方案
根据你的交互需求,可选择以下两种方案:
方案1:先回到首页,再从首页跳转到高分页
如果你的交互逻辑要求先关闭游戏页回到首页,再弹出高分页,需要把跳转逻辑交给下层的 homeScreenViewController 执行:
@objc func updateTimer() { if secondsRemaining > 0 { secondsRemaining -= 1 timerLabel.text = "Timer:\(secondsRemaining)" print(secondsRemaining) } else { self.dismiss(animated: true) { [weak self] in guard let self = self, let homeVC = self.presentingViewController as? HomeScreenViewController else { return } // 若首页已绑定到高分页的segue,直接让首页执行跳转 homeVC.performSegue(withIdentifier: "homeToHighscore", sender: nil) // 无segue也可以手动跳转,示例: // let highscoreVC = HighscoreViewController() // homeVC.navigationController?.pushViewController(highscoreVC, animated: true) } } }
注意:原绑定在当前游戏控制器上的 gameScreenToHighscore 已经无法使用,需要在首页的storyboard里新增绑定到高分页的segue
方案2:直接从游戏页跳转到高分页,不需要回到首页
如果不需要展示回到首页的过渡过程,直接调整代码顺序,在dismiss完成后执行跳转(或者直接去掉dismiss逻辑):
@objc func updateTimer() { if secondsRemaining > 0 { secondsRemaining -= 1 timerLabel.text = "Timer:\(secondsRemaining)" print(secondsRemaining) } else { // 先无动画关闭当前游戏页,再执行跳转,用户看不到回到首页的过程 self.dismiss(animated: false) { [weak self] in self?.performSegue(withIdentifier: "gameScreenToHighscore", sender: self) } // 不需要回到首页的话也可以直接去掉dismiss,直接执行segue // self.performSegue(withIdentifier: "gameScreenToHighscore", sender: self) } }
其他注意事项
- 所有异步回调中要加
[weak self]避免循环引用,防止内存泄漏 - 请确认segue的identifier拼写和storyboard中的绑定完全一致
- 如果你的页面由导航控制器管理,直接调用导航控制器的push方法比segue灵活性更高
内容的提问来源于stack exchange,提问作者user7280945
相关产品推荐
相关产品推荐

