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

iOS 17 iPad端UITabBarController初始化崩溃求助

问题:iOS 17 iPad端UITabBarController启动崩溃

同版本iOS的iPhone上UITabBarController功能正常,但iOS 17的iPad端启动时崩溃,开发环境为Xcode 15.4。

DashboardVC实现代码

class DashboardVC: UITabBarController, UITabBarControllerDelegate {
    var presenter: DashboardPresentation?
    var controllersList: [UIViewController]?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.navigationController?.navigationBar.isHidden = true
       // self.navigationItem.title = "Check Me".localized()
        self.delegate = self
        self.tabBar.shadowImage = nil
        
        self.tabBar.layer.borderWidth = 1
        self.tabBar.layer.borderColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
        self.tabBar.clipsToBounds = true
        setubTabControllers()
    }
    
    func setubTabControllers() {
        self.tabBar.tintColor = #colorLiteral(red: 0.05490196078, green: 0.3764705882, blue: 0.8980392157, alpha: 1)
        self.tabBar.barTintColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
        self.tabBar.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
        self.tabBar.unselectedItemTintColor =  #colorLiteral(red: 0.6000000238, green: 0.6000000238, blue: 0.6000000238, alpha: 1)
        self.tabBar.isTranslucent = false
        self.tabBar.itemPositioning = .centered
        
        let homeVC = HomeRouter.assembleModule(title: msgTitle, message: message, goToChat: goToChat, returnNav: true)

        homeVC.tabBarItem = UITabBarItem(title: "Home".localized(), image: UIImage(named: "Home-inactive")?.withRenderingMode(.alwaysOriginal), selectedImage: UIImage(named: "Home")?.withRenderingMode(.alwaysOriginal))
        
        let favVC = NotificationsListRouter.assembleModule(dashboardDelegate: self, returnNav: true)
        favVC.tabBarItem = UITabBarItem(title: "Notifications".localized(), image: UIImage(named: "Notifications-inactive")?.withRenderingMode(.alwaysOriginal), selectedImage: UIImage(named: "Notifications-active")?.withRenderingMode(.alwaysOriginal))
        
        let searchVC = ResultsRouter.assembleModule(returnNav: true)
        searchVC.tabBarItem = UITabBarItem(title: "Results".localized(), image: UIImage(named: "result-inactive")?.withRenderingMode(.alwaysOriginal), selectedImage: UIImage(named: "result-active")?.withRenderingMode(.alwaysOriginal))

        let accountVC = AccountRouter.assembleModule(returnNav: true)
        accountVC.tabBarItem = UITabBarItem(title: "Profile".localized(), image: UIImage(named: "profile-inactive")?.withRenderingMode(.alwaysOriginal), selectedImage: UIImage(named: "profile-active")?.withRenderingMode(.alwaysOriginal))
        
        if UIDevice.current.userInterfaceIdiom == .pad {
            homeVC.tabBarItem.setTitleTextAttributes([NSAttributedString.Key.font: UIFont.systemFont(ofSize: 20)], for: .normal)
            favVC.tabBarItem.setTitleTextAttributes([NSAttributedString.Key.font: UIFont.systemFont(ofSize: 20)], for: .normal)
            searchVC.tabBarItem.setTitleTextAttributes([NSAttributedString.Key.font: UIFont.systemFont(ofSize: 20)], for: .normal)
            accountVC.tabBarItem.setTitleTextAttributes([NSAttributedString.Key.font: UIFont.systemFont(ofSize: 20)], for: .normal)
        } else {
            homeVC.tabBarItem.setTitleTextAttributes([NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 15)], for: .normal)
            favVC.tabBarItem.setTitleTextAttributes([NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 15)], for: .normal)
            searchVC.tabBarItem.setTitleTextAttributes([NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 15)], for: .normal)
            accountVC.tabBarItem.setTitleTextAttributes([NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 15)], for: .normal)
        }
        
        controllersList = [homeVC, favVC, searchVC, accountVC]
        self.viewControllers = controllersList
    }
    
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
    }
}

崩溃报错信息

*** Assertion failure in UITraitCollection * _Nonnull _UIGetCurrentFallbackTraitCollection(void)(), _UIFallbackEnvironment_NonARC.m:117
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'A trait environment returned a trait collection with unspecified values for traits that are not allowed to be unspecified. This is a serious application bug and will cause undefined behavior. This issue may be caused by your class overriding the traitCollection property getter, which is not supported. Make sure to use the appropriate API if you are trying to override traits. Trait Environment: <UITabBarSwappableImageView: 0x105b2bf90; frame = (0 0; 0 0); opaque = NO; userInteractionEnabled = NO; image = <UIImage:0x6000030058c0 CGImage anonymous; (23 23)@2>; layer = <CALayer: 0x600000293bc0>>; Trait Collection: <UITraitCollection: 0x105a54950; HorizontalSizeClass = Compact, PreferredContentSizeCategory = L>'

解决方案

问题根源

iOS 17中iPad的UITabBar内部视图(如UITabBarSwappableImageView)在初始化阶段TraitCollection未完全加载完成,此时直接设置tabBarItem的文字属性(如字体)会触发系统断言,因为TraitCollection缺失必填项。

修复步骤

  1. 延迟设置tabBarItem字体属性
    将原来在setubTabControllers中的字体设置逻辑移到viewWillAppear方法中,确保视图层级和TraitCollection已完全初始化:

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        configureTabBarItemFonts()
    }
    
    private func configureTabBarItemFonts() {
        let (fontSize, font) = UIDevice.current.userInterfaceIdiom == .pad 
            ? (20, UIFont.systemFont(ofSize: 20)) 
            : (15, UIFont.boldSystemFont(ofSize: 15))
        
        viewControllers?.forEach { vc in
            vc.tabBarItem.setTitleTextAttributes([.font: font], for: .normal)
        }
    }
    

    同时删除setubTabControllers中原来的if-else字体设置代码块。

  2. 备选方案:全局配置UITabBar外观
    可以在App启动时(如AppDelegate或SceneDelegate)通过UITabBar的外观代理全局配置字体,避免在控制器中单独设置:

    UITabBar.appearance().titleTextAttributes = [
        .font: UIFont.boldSystemFont(ofSize: 15)
    ]
    UITabBar.appearance().setTitleTextAttributes(
        [.font: UIFont.systemFont(ofSize: 20)], 
        for: .normal, 
        compatibleWith: UITraitCollection(userInterfaceIdiom: .pad)
    )
    
  3. 检查子控制器配置
    确认子控制器的assembleModule方法中没有提前创建tabBarItem或修改TraitCollection的操作,确保子控制器被添加到UITabBarController之后再配置tabBarItem属性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:14:52