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的父控制器处理,避免层级依赖:
- 首先在
TestVC类中定义回调属性:
class TestVC: UIViewController { // 定义dismiss完成后的回调闭包 var dismissCompletion: (() -> Void)? // 其余原有代码... }
- 在present
TestVC的父控制器中给闭包赋值:
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)
- 在TestVC执行dismiss时触发回调:
dismiss(animated: true) { [weak self] in self?.dismissCompletion?() }
注意事项
所有闭包中要添加[weak self]修饰,避免循环引用导致内存泄漏。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

