Swift 4.2中如何在运行时根据变量切换Tab Bar Item非选中图片?
解决方案:动态切换Tab Bar Item非选中图片
嘿,我来帮你搞定这个在Swift 4.2、Xcode 10.1环境下动态切换Tab Bar Item非选中图片的问题!你之前遇到的问题大概率是因为只在初始化阶段设置了一次,没有监听truth变量的变化,或者没有处理图片的渲染模式导致颜色不生效。下面给你两种可行的实现方式:
方案一:给truth变量添加属性观察者,实时更新
这种方式适合truth变量在当前视图控制器中管理的场景,当truth的值变化时,立刻触发Tab Bar Item的图片更新:
// 假设truth是当前控制器的属性 var truth: Bool = false { didSet { // 确保能获取到对应的Tab Bar Item guard let tabBarItems = tabBarController?.tabBar.items else { return } let targetTabItem = tabBarItems[0] // 根据truth状态选择非选中图片 let unselectedImageName = truth ? "globe_red" : "globe" // 关键:设置图片的渲染模式为.alwaysOriginal,避免被TabBar的tintColor覆盖颜色 targetTabItem.image = UIImage(named: unselectedImageName)?.withRenderingMode(.alwaysOriginal) // 重新确认选中图片,防止被意外修改 targetTabItem.selectedImage = UIImage(named: "globe")?.withRenderingMode(.alwaysOriginal) } }
注意点:
- 必须设置
withRenderingMode(.alwaysOriginal):默认情况下UIImage会使用.automatic渲染模式,TabBar的tintColor会覆盖图片原本的颜色,导致你的红色图片显示不出来。 - 如果你的
truth是在其他类中管理的,可以把这个更新逻辑封装成一个公共方法,在truth变化时调用。
方案二:子类化TabBarController,监听状态变化
如果truth是全局状态(比如存储在UserDefaults或者全局单例中),可以通过子类化TabBarController来统一管理Tab Bar的状态更新:
第一步:创建自定义TabBarController
class CustomTabBarController: UITabBarController { override func viewDidLoad() { super.viewDidLoad() // 初始化时先设置一次初始状态 updateTabBarItemImage() // 添加通知观察者,监听truth的变化 NotificationCenter.default.addObserver( self, selector: #selector(updateTabBarItemImage), name: NSNotification.Name("TruthStateDidChange"), object: nil ) } @objc private func updateTabBarItemImage() { guard let tabBarItems = tabBar.items else { return } let targetItem = tabBarItems[0] // 替换成你的truth获取方式,比如从全局单例或UserDefaults读取 let isTruthEnabled = YourGlobalState.shared.truth let unselectedImageName = isTruthEnabled ? "globe_red" : "globe" targetItem.image = UIImage(named: unselectedImageName)?.withRenderingMode(.alwaysOriginal) targetItem.selectedImage = UIImage(named: "globe")?.withRenderingMode(.alwaysOriginal) } deinit { // 记得移除观察者,避免内存泄漏 NotificationCenter.default.removeObserver(self) } }
第二步:在truth变化时发送通知
// 假设truth在全局单例中 class YourGlobalState { static let shared = YourGlobalState() var truth: Bool = false { didSet { // 发送通知告知TabBarController更新 NotificationCenter.default.post( name: NSNotification.Name("TruthStateDidChange"), object: nil ) } } }
额外提示:避免初始化时tabBarController为nil的问题
如果你在子控制器的viewDidLoad中尝试获取tabBarController,可能会因为控制器还没被添加到TabBarController中而返回nil。这种情况下,可以把初始化代码放到viewWillAppear中:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 初始化时设置一次图片状态 updateTabBarItemImage() } private func updateTabBarItemImage() { guard let tabBarItems = tabBarController?.tabBar.items else { return } let targetItem = tabBarItems[0] let unselectedImageName = truth ? "globe_red" : "globe" targetItem.image = UIImage(named: unselectedImageName)?.withRenderingMode(.alwaysOriginal) targetItem.selectedImage = UIImage(named: "globe")?.withRenderingMode(.alwaysOriginal) }
内容的提问来源于stack exchange,提问作者ljelliot
相关产品推荐
相关产品推荐

