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解耦,不让前者依赖后者的类型,用闭包回调是更好的选择。具体步骤如下:
- 先在
LocalPwdVC(也就是你的ViewController2)里定义一个闭包属性:
class LocalPwdVC: UIViewController { // 定义一个可选闭包,用于dismiss完成后的回调 var onDismissComplete: (() -> Void)? // ...其他原有代码 @IBAction func btnVerify(_ sender: Any) { self.dismiss(animated: true) { [weak self] in // 触发回调 self?.onDismissComplete?() } } }
- 然后在
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
相关产品推荐
相关产品推荐

