在TabBar上以.overFullScreen风格弹出的VC上再次弹出同风格VC失败的问题求助
解决方案:在OverFullScreen模态VC上再次弹出模态VC的问题
我之前也踩过这个坑,咱们先拆解下报错的核心原因:iOS的模态呈现机制是链式层级的,当一个控制器(比如你报错里的UINavigationController: 0x7fb10282da00)已经在presenting另一个控制器(Screen1VC)时,它不能再直接被用来present新的控制器,必须找到当前最顶层的、处于活跃状态的presented控制器来发起新的present操作。
下面是我亲测有效的几种解决方案:
方法1:通过扩展获取顶层Presented控制器
写一个UIViewController的扩展,递归找到当前应用中最顶层的presented控制器,用它来present新的VC:
extension UIViewController { var topPresentedViewController: UIViewController { if let presentedVC = presentedViewController { return presentedVC.topPresentedViewController } return self } }
然后在需要present VC1的地方,这样调用:
let vc1 = Screen1VC() vc1.modalPresentationStyle = .overFullScreen // 获取根控制器的顶层presented控制器来发起present UIApplication.shared.keyWindow?.rootViewController?.topPresentedViewController.present(vc1, animated: true)
方法2:直接从当前活跃的VC发起present
如果你的操作是在VC2内部触发的(比如点击VC2上的按钮弹出VC1),直接用VC2自身来present即可,不要用原来的TabBar导航控制器:
// 在VC2的代码中(比如按钮点击事件里) @IBAction func showVC1Tapped(_ sender: UIButton) { let vc1 = Screen1VC() vc1.modalPresentationStyle = .overFullScreen self.present(vc1, animated: true) }
方法3:确保前一个模态VC已完成呈现
如果你的场景是需要在某个模态VC呈现完成后再弹出新的VC,可以利用present(_:animated:completion:)的回调函数,在第一个模态VC完全呈现后再发起第二个present:
// 先present VC1,完成后再present新的VC let vc1 = Screen1VC() vc1.modalPresentationStyle = .overFullScreen self.present(vc1, animated: true) { let targetVC = Screen2VC() // 或你需要弹出的其他VC targetVC.modalPresentationStyle = .overFullScreen vc1.present(targetVC, animated: true) }
核心思路就是:永远让当前最顶层的、没有正在presenting其他控制器的VC来发起新的模态呈现请求,这样就能避开iOS的模态层级校验报错。
内容的提问来源于stack exchange,提问作者Kudos
相关产品推荐
相关产品推荐

