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

iOS开发中dismiss formSheet视图后无法执行popToRootViewController问题

iOS dismiss formSheet后popToRootViewController不生效的解决方案

问题原因

你当前在presented的TestVC中调用的self.navigationController,是你用来包裹TestVC、专门用于present的临时UINavigationController实例。当dismiss操作执行完成后,这个presented的导航控制器已经被系统释放,所以后续调用self.navigationController?.popToRootViewController的调用对象已经为nil,自然不会生效。

解决方案

方案1:直接获取底层导航栈执行操作

在dismiss的回调中,通过presentingViewController获取最初弹出formSheet的底层控制器所属的导航栈,再执行pop操作:

// 写在TestVC中的dismiss逻辑
dismiss(animated: true) { [weak self] in
    // 获取底层父控制器的导航栈
    guard let rootNav = self?.presentingViewController?.navigationController else { return }
    rootNav.popToRootViewController(animated: true)
}

方案2:通过闭包回调处理(更解耦)

通过自定义闭包把pop逻辑交给present的父控制器处理,避免层级依赖:

  1. 首先在TestVC类中定义回调属性:
class TestVC: UIViewController {
    // 定义dismiss完成后的回调闭包
    var dismissCompletion: (() -> Void)?
    // 其余原有代码...
}
  1. 在presentTestVC的父控制器中给闭包赋值:
let controller = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "test") as! TestVC
// 赋值闭包,在父控制器中处理pop逻辑
controller.dismissCompletion = { [weak self] in
    self?.navigationController?.popToRootViewController(animated: true)
}
let navigationController = UINavigationController(rootViewController: controller)
navigationController.modalPresentationStyle = .formSheet
self.present(navigationController, animated: true, completion: nil)
  1. 在TestVC执行dismiss时触发回调:
dismiss(animated: true) { [weak self] in
    self?.dismissCompletion?()
}

注意事项

所有闭包中要添加[weak self]修饰,避免循环引用导致内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 20:09:04