问题 当present 多个页面时报错 或崩溃
Attempt to present <LZPresentDemo.FirstDetailViewController: 0x10ab0b350> on <UITabBarController: 0x10e037000> (from <LZPresentDemo.FirstViewController: 0x10aa152a0>) which is already presenting <LZPresentDemo.SecondDetailViewController: 0x10ab1caf0>.
有说明可知 ,当有present页面时 不能再次present,看视图逻辑
也就是 ① navB2 present B2 后,不能 再次 navB2 prensent A1.
② navB2 present B2 后,不能 再次 navA1 prensent A1.
怎么解决问题呢?
答案:就是由最顶端的 ViewController 再次Prensent 我们想要的ViewController
这下就很清楚了:使用present去弹模态视图的时候,只能用最顶层的的控制器去弹,用底层的控制器去弹会失败,并抛出警告。
比如 navB2 present B2 后,再有B2 prensent A1.解决问题。
多次弹出的视图层次
nav.vcB2 present B2 的 各数据
示例
let secondDetailVC = SecondDetailViewController()
secondDetailVC.modalPresentationStyle = .custom
print("弹出 secondDetailVC = \(secondDetailVC) title = \(secondDetailVC.title) \n")
self.present(secondDetailVC, animated: true) { [weak self] in
guard let self = self else { return }
print("弹出 secondDetailVC , nav.presentedViewController = \(self.navigationController?.presentedViewController),nav.presentingViewController = \(self.navigationController?.presentingViewController)")
print("弹出 secondDetailVC , nav.vc.presentedViewController = \(self.presentedViewController),nav.vc.presentingViewController = \(self.presentingViewController)")
print("弹出 secondDetailVC , secondDetailVC.presentedViewController = \(secondDetailVC.presentedViewController),secondDetailVC.presentingViewController = \(secondDetailVC.presentingViewController); title = \(secondDetailVC.title)")
if let sceneDelegate = UIApplication.shared.connectedScenes
.first?.delegate as? SceneDelegate
{
// 你现在可以使用sceneDelegate来访问Scene相关的方法和属性
let tabbarVC = sceneDelegate.tabbarVC
let vcA1 = sceneDelegate.navVCA1
let navA1 = vcA1?.navigationController
print("弹出 secondDetailVC , navA1.presentedViewController = \(navA1?.presentedViewController),nav.presentingViewController = \(navA1?.presentingViewController)")
print("弹出 secondDetailVC , vcA1.presentedViewController = \(vcA1?.presentedViewController),vcA1.presentingViewController = \(vcA1?.presentingViewController)")
print("弹出 secondDetailVC , tabbarVC.presentedViewController = \(tabbarVC?.presentedViewController),tabbarVC.presentingViewController = \(tabbarVC?.presentingViewController) \n")
}
}
规律
nav.vcB2 present B2
B2 的 presentingViewController =UITabBarController重点
tabbarVC的 presentedViewController =navB2.vc.presentedViewController =navB2.presentedViewController =navA1.vc.presentedViewController =navA1.presentedViewController =B2
注意tabbar 意想不到;
tabbar 里的 nav, 和 nav 里的vcpresentedViewController 都是 B2更意想不到
获取最上方的ViewController
我简单地写了个方法来获取传入viewController的最顶层子节点,大家可以参考下
//获取最顶层的弹出视图,没有子节点则返回本身 注意:当有多个nav present 多个vc 时,此方法不使用
static func topestPresentedViewControllerForVC(viewController: UIViewController) -> UIViewController{
var topestVc = viewController
while let topVC = topestVc.presentedViewController {
topestVc = topVC
}
return topestVc
}
//获取最顶层的弹出视图,没有子节点则返回本身
static func topestPresentedViewControllerForVC(tabViewController: UITabBarController) -> UIViewController{
var topestVc: UIViewController = tabViewController
while let topVC = topestVc.presentedViewController {
topestVc = topVC
}
return topestVc
}
demo 地址 github.com/lizhi0123/L…
感谢评论区 解决方案