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

Swift 4中如何在dismiss模态VC后设置新的Root ViewController?

解决方案:模态VC Dismiss后替换根ViewController

当然可以实现这个需求!下面我会用最直观且解耦的方式来帮你完成这个逻辑,主要通过闭包回调的方式处理,避免代码耦合性过高的问题。

步骤1:在模态ViewController中添加回调闭包

首先,在你用来模态呈现的ViewController里,定义一个闭包属性,用来在dismiss完成后通知外部执行后续逻辑:

class ModalViewController: UIViewController {
    // 定义回调闭包,dismiss完成后触发
    var onDismissComplete: (() -> Void)?
    
    // 假设这是你点击后触发dismiss的按钮方法
    @IBAction func confirmButtonTapped(_ sender: UIButton) {
        // 执行dismiss,在completion回调里触发自定义闭包
        dismiss(animated: true) {
            self.onDismissComplete?()
        }
    }
}

步骤2:在原根ViewController中处理回调逻辑

回到你原来嵌套在NavigationController里的ViewController(假设叫RootTableViewController),在present模态VC的时候,给这个闭包赋值,把替换根VC的逻辑写在里面:

class RootTableViewController: UIViewController {
    // 导航栏添加按钮的点击方法
    @IBAction func addButtonTapped(_ sender: UIBarButtonItem) {
        let modalVC = ModalViewController(nibName: "ModalViewController", bundle: nil)
        
        // 设置回调闭包,处理dismiss后的根VC替换逻辑
        modalVC.onDismissComplete = { [weak self] in
            guard let self = self else { return }
            
            // 1. 创建你想要设置为新根的ViewController
            let newRootVC = NewRootViewController(nibName: "NewRootViewController", bundle: nil)
            
            // 2. 如果需要包裹NavigationController,就创建新的导航控制器
            let newNavController = UINavigationController(rootViewController: newRootVC)
            
            // 3. 获取当前应用的Window,替换根ViewController
            // 适配iOS 13+的多场景模式
            if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
               let window = windowScene.windows.first {
                // 添加过渡动画,让切换更流畅
                UIView.transition(with: window, duration: 0.3, options: .transitionCrossDissolve, animations: {
                    window.rootViewController = newNavController
                }, completion: nil)
            }
        }
        
        // 模态呈现VC
        present(modalVC, animated: true)
    }
}

关键注意点

  • 避免内存泄漏:用[weak self]捕获self,防止循环引用导致的内存泄漏问题。
  • iOS版本适配:iOS 13之后应用支持多window场景,需要通过connectedScenes获取当前活跃的window,而不是直接使用UIApplication.shared.windows.first。
  • 过渡动画:添加UIView.transition可以让根VC切换更平滑,你也可以根据需求选择其他动画选项(比如.transitionFlipFromRight等)。

其他可选方式(不推荐但可用)

如果你觉得闭包不够灵活,也可以用NotificationCenter实现:

  1. 在原根VC的viewDidLoad里监听自定义通知。
  2. 在模态VC的dismiss completion里发送该通知。
  3. 原根VC收到通知后执行替换根VC的逻辑。

不过闭包更适合这种一对一的回调场景,代码更清晰,也不容易出现通知滥用的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:20:50