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

Swift开发:从导航控制器dismiss后如何呈现新视图控制器?

解决Dismiss后呈现新视图控制器的问题

嘿,我来帮你搞定这个问题!你现在的场景是:从导航控制器里present了LocalPwdVC,在dismiss这个模态视图控制器之后,想要呈现另一个新的视图控制器对吧?这里的核心是要在dismiss完成后,回到原导航栈的上下文里进行操作,我给你两种可行的方案:

方案1:直接在Dismiss的Completion中获取原导航控制器

你可以在ViewController2的btnVerify方法里,利用presentingViewController拿到原来的ViewController1,再通过它获取导航控制器,然后就能push或present新的VC了。代码修改如下:

@IBAction func btnVerify(_ sender: Any) {
    self.dismiss(animated: true) { [weak self] in
        // 用weak self避免循环引用,防止内存泄漏
        guard let presentingVC = self?.presentingViewController as? ViewController1 else {
            return
        }
        // 实例化你要跳转的新视图控制器(记得替换成你的标识符和类型)
        guard let newVC = presentingVC.storyboard?.instantiateViewController(withIdentifier: "YourNewVCID") as? YourNewVCClass else {
            return
        }
        // 选择push到导航栈,或者用present模态呈现
        presentingVC.navigationController?.pushViewController(newVC, animated: true)
        // 如果需要模态呈现的话,用下面这行:
        // presentingVC.navigationController?.present(newVC, animated: true, completion: nil)
    }
}

注意点:

  • 一定要加[weak self],不然completion闭包会持有ViewController2的实例,导致内存泄漏。
  • 类型转换as? ViewController1是为了确保我们拿到的是正确的原视图控制器,避免后续操作出错。

方案2:用闭包回调解耦(推荐)

如果想让LocalPwdVC和ViewController1解耦,不让前者依赖后者的类型,用闭包回调是更好的选择。具体步骤如下:

  1. 先在LocalPwdVC(也就是你的ViewController2)里定义一个闭包属性:
class LocalPwdVC: UIViewController {
    // 定义一个可选闭包,用于dismiss完成后的回调
    var onDismissComplete: (() -> Void)?
    
    // ...其他原有代码
    
    @IBAction func btnVerify(_ sender: Any) {
        self.dismiss(animated: true) { [weak self] in
            // 触发回调
            self?.onDismissComplete?()
        }
    }
}
  1. 然后在ViewController1的pushTo方法里,给这个闭包赋值,在闭包里处理跳转逻辑:
func pushTo(viewController: UIViewController) {
    guard let showLocalPwd = self.storyboard?.instantiateViewController(withIdentifier: "LocalPwdVC") as? LocalPwdVC else {
        return
    }
    // 设置回调闭包
    showLocalPwd.onDismissComplete = { [weak self] in
        guard let self = self else { return }
        // 实例化新视图控制器
        guard let newVC = self.storyboard?.instantiateViewController(withIdentifier: "YourNewVCID") as? YourNewVCClass else {
            return
        }
        // 执行跳转
        self.navigationController?.pushViewController(newVC, animated: true)
    }
    self.navigationController?.present(showLocalPwd, animated: true, completion: nil)
}

为什么推荐这个方案?

这种方式让两个视图控制器之间没有直接的依赖关系,LocalPwdVC不需要知道是谁present了它,只需要在dismiss后触发回调即可,代码更灵活、易维护,也符合iOS开发的设计原则。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:38:20