You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中dismiss模态VC后调用popViewController无效问题

问题场景

需要在关闭模态展示的视图控制器后,执行popViewController返回导航栈的上一级页面,以下两种实现均无法正常生效:
第一种实现:

func showMessage(withTitle title: String, message: String) {

        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)

        let alertAction = UIAlertAction(title: "ok", style: .default) { (_) in
            self.dismiss(animated: true) {
                self.navigationController?.popViewController(animated: true)
            }
        }
        
        alert.addAction(alertAction)
        
        present(alert, animated: true, completion: nil)
    }

第二种实现:

let controller = ViewController()             
controller?.popViewController(animated: true)
失效原因
  • 第一种写法:调用dismiss的目标错误。代码触发时最顶层的模态视图是UIAlertController,self.dismiss仅会关闭当前弹出的警告框,不会关闭你需要dismiss的模态VC。回调触发时当前控制器仍处于模态展示状态,并未处于导航控制器的栈结构中,self.navigationController为nil,pop操作无法执行。
  • 第二种写法:操作的控制器实例错误。通过ViewController()初始化的是全新的、未被加入任何导航栈的孤立实例,对该实例调用pop方法不会对当前已展示的界面产生任何效果。
正确实现

核心逻辑:弹出当前模态VC的控制器(即self.presentingViewController)才是处于导航栈内的页面,需要先dismiss当前模态VC,dismiss完成后再由这个弹出方的导航控制器执行pop操作。
替换alert按钮的回调代码即可:

let alertAction = UIAlertAction(title: "ok", style: .default) { [weak self] (_) in
    guard let self = self else { return }
    // 获取弹出当前模态VC的上级页面
    guard let presentingVC = self.presentingViewController else { return }
    // 兼容presentingVC是普通页面/导航控制器两种场景
    let targetNav = (presentingVC as? UINavigationController) ?? presentingVC.navigationController
    self.dismiss(animated: true) {
        targetNav?.popViewController(animated: true)
    }
}

提示:闭包内使用[weak self]是为了避免循环引用导致的内存泄漏。

内容的提问来源于stack exchange,提问作者JuFa512

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 20:31:11