Swift 3设置Tab Bar徽章报错求助:索引越界问题
解决你的Swift TabBar Badge设置问题
嘿,我来帮你搞定这个问题!首先看你的错误提示——index 2 beyond bounds [0 .. 0],这说明你拿到的tabBar.items数组只有1个元素,根本没有第3个item(索引2)可以访问,这就是崩溃的直接原因。
问题根源分析
你说TabBar有4个item,但代码里只拿到1个,大概率是下面两种情况之一:
- 你的这段代码所在的ViewController不是TabBarController的直接子控制器(比如它嵌套在UINavigationController里,而这个导航控制器才是TabBar的item);
- 在
viewDidAppear调用时,TabBarController的items还没完全初始化完成,导致获取到的数组不完整。
解决方案
我给你几个靠谱的解决办法,按优先级推荐:
方法1:直接在自定义TabBarController里设置(最推荐)
创建一个UITabBarController的子类,把设置badge的代码放在这里,这样能确保你操作的是正确的TabBar实例,而且时机最稳妥:
class CustomTabBarController: UITabBarController { override func viewDidLoad() { super.viewDidLoad() // 先判断items数量足够,避免越界 guard let tabItems = tabBar.items, tabItems.count > 2 else { print("TabBar items数量不足") return } let thirdTabItem = tabItems[2] thirdTabItem.badgeValue = "New" } }
然后在Storyboard里把你的TabBarController的Class设置为CustomTabBarController就行。
方法2:确保拿到正确的TabBarController(如果代码必须放在子VC里)
如果你的代码必须写在某个子ViewController里,那可以直接从根控制器获取TabBar实例,避免当前VC的tabBarController指向错误:
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // 获取根控制器的TabBarController(适配iOS13+多场景) guard let tabBarController = UIApplication.shared.connectedScenes .compactMap({ $0 as? UIWindowScene }) .first?.windows .first(where: { $0.isKeyWindow })?.rootViewController as? UITabBarController else { print("无法获取TabBarController") return } guard let tabItems = tabBarController.tabBar.items, tabItems.count > 2 else { print("TabBar items数量不足") return } let thirdTabItem = tabItems[2] thirdTabItem.badgeValue = "New" }
方法3:先排查TabBar的配置问题
先在代码里加一行打印,确认实际拿到的items数量:
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) print("当前TabBar items数量:\(self.tabBarController?.tabBar.items?.count ?? 0)") // 后面的代码... }
如果打印出来是1,那你得去Storyboard里检查:
- 你的TabBarController是不是真的添加了4个ViewController作为子控制器;
- 每个子控制器的TabBarItem是不是都正确配置了;
- 有没有不小心把某个ViewController的TabBarItem隐藏了。
额外提醒
永远记得在访问数组索引前先判断数组的长度,用guard或者if let做安全校验,就像上面代码里那样,能避免很多越界崩溃的问题。
内容的提问来源于stack exchange,提问作者NelbeDG
相关产品推荐
相关产品推荐

