位置:首页 > Swift > iOS Swift连续present多个页面报错或崩溃解决方法

iOS Swift连续present多个页面报错或崩溃解决方法

时间:2026-08-21  |  作者:电竞小硕  |  阅读:0

问题 当present 多个页面时报错 或崩溃

Attempt to present on (from ) which is already presenting .

有说明可知,当有present页面时,不能再次present,要先看视图逻辑。

也就是:

  • ① na vB2 present B2 后,不能再次 na vB2 prensent A1。

  • ② na vB2 present B2 后,不能再次 na vA1 prensent A1。

怎么解决问题呢?

答案就是通过最顶端的ViewController再次Prensent我们期望的ViewController。

这下就清晰了:在使用present弹出模态视图时,必须使用最顶层的控制器来进行操作,若使用底层的控制器进行弹出,将会失败并抛出警告

例如,在na vB2 present B2之后,再由B2 prensent A1,即可解决问题。

多次弹出的视图层次

na v.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 , na v.presentedViewController =  (self.na vigationController.presentedViewController),na v.presentingViewController = (self.na vigationController.presentingViewController)")
            
            print("弹出 secondDetailVC , na v.vc.presentedViewController =  (self.presentedViewController),na v.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.na vVCA1
                let na vA1 = vcA1.na vigationController
                
                print("弹出 secondDetailVC , na vA1.presentedViewController =  (na vA1.presentedViewController),na v.presentingViewController = (na vA1.presentingViewController)")
                print("弹出 secondDetailVC , vcA1.presentedViewController =  (vcA1.presentedViewController),vcA1.presentingViewController = (vcA1.presentingViewController)")
                
                
                print("弹出 secondDetailVC , tabbarVC.presentedViewController =  (tabbarVC.presentedViewController),tabbarVC.presentingViewController = (tabbarVC.presentingViewController) n")
            }
        }
        

规律

na v.vcB2 呈现 B2。

B2 的 presentingViewController 为 UITabBarController 重点

tabbarVC 的 presentedViewController 等于 na vB2.vc.presentedViewController,也等于 na vB2.presentedViewController,还等于 na vA1.vc.presentedViewController,最终等于 na vA1.presentedViewController,即 B2

注意tabbar 意想不到

tabbar 里的 na v, 和 na v 里的vc presentedViewController 都是 B2 更意想不到

获取最上方的ViewController

我简单地写了个方法来获取传入viewController的最顶层子节点,大家可以参考下。

 //获取最顶层的弹出视图,没有子节点则返回本身 注意:当有多个na v 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
    }

补充说明

  • 核心结论:present 多个页面时,后续弹出必须从最顶层的ViewController发起。

  • 错误原因:当前已有控制器正在 presenting 时,再从底层控制器发起 present,就会报错或警告。

  • 处理方式:先找到当前最上方的控制器,再由它 present 目标页面。

demo 地址 github.com/lizhi0123/L…

感谢评论区 解决方案

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多