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实现:
- 在原根VC的
viewDidLoad里监听自定义通知。 - 在模态VC的dismiss completion里发送该通知。
- 原根VC收到通知后执行替换根VC的逻辑。
不过闭包更适合这种一对一的回调场景,代码更清晰,也不容易出现通知滥用的问题。
内容的提问来源于stack exchange,提问作者Jurie
相关产品推荐
相关产品推荐

