使用Storyboard Reference时,自定义UITabBarItem获取图片值失败如何解决?
解决自定义UITabBar配合Storyboard Reference时无法获取TabBarItem图片的问题
我完全懂你现在的困惑——自定义TabBar之前用得好好的,一加上Storyboard Reference就拿不到TabBarItem的图片值了,而且设置逻辑和之前没区别,这种“无差别操作却出问题”的情况确实很闹心。
问题根源分析
核心原因出在Storyboard Reference的延迟加载特性上:
- 不用Storyboard Reference时,所有子控制器都直接在当前Storyboard里,初始化时机早,当你在
CustomTabBarController的viewDidLoad里调用setup()时,TabBarItem的图片已经被正确加载了。 - 但用了Storyboard Reference后,对应的子控制器不会在TabBarController初始化时立即加载,而是会延迟到第一次需要它的时候(比如切换到该标签页)。这就导致你在
viewDidLoad里调用setup()时,通过datasource拿到的TabBarItem其实还没完成完整初始化,它的image属性还是空的。
具体解决方案
下面给你几个可行的修复方案,按推荐优先级排序:
1. 延迟自定义TabBar的初始化时机
把自定义TabBar的创建和setup()调用从viewDidLoad移到viewDidAppear里,此时所有通过Storyboard Reference关联的子控制器已经完成初始化,TabBarItem的图片也能正常获取了:
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // 确保只初始化一次,避免重复添加 guard self.view.subviews.first(where: { $0 is CustomTabBar }) == nil else { return } let customTabBar = CustomTabBar(frame: self.tabBar.frame) customTabBar.datasource = self customTabBar.delegate = self customTabBar.setup() self.tabBar.isHidden = true self.view.addSubview(customTabBar) }
2. 手动预加载所有子控制器
如果不想等到viewDidAppear,可以在viewDidLoad里手动触发所有子控制器的初始化,强制加载它们的TabBarItem:
override func viewDidLoad() { super.viewDidLoad() // 预加载所有子控制器,触发TabBarItem的初始化 self.viewControllers?.forEach { controller in _ = controller.view // 访问view属性会强制控制器完成初始化 } let customTabBar = CustomTabBar(frame: self.tabBar.frame) customTabBar.datasource = self customTabBar.delegate = self customTabBar.setup() self.tabBar.isHidden = true self.view.addSubview(customTabBar) }
3. 检查CustomTabBarItem的图片处理逻辑
另外可以确认下CustomTabBarItem的setup()方法是否正确处理了图片的渲染模式,有时候系统默认的template图片会导致显示异常,建议显式设置渲染模式:
func setup(_ item: UITabBarItem) { // 处理普通状态图片 if let image = item.image?.withRenderingMode(.alwaysOriginal) { self.iconView.image = image } // 处理选中状态图片 if let selectedImage = item.selectedImage?.withRenderingMode(.alwaysOriginal) { self.selectedIconView.image = selectedImage } // 其他标题等设置 self.titleLabel.text = item.title }
总结
本质上就是Storyboard Reference的延迟加载打乱了你原本的初始化时机,只要确保在所有TabBarItem都完成初始化后再调用setup(),问题就能解决。
内容的提问来源于stack exchange,提问作者cusmar
相关产品推荐
相关产品推荐

