iOS 13点击按钮切换主题时,如何运行时修改TabBar标题与图标颜色?
iOS 13 运行时动态修改 TabBar 外观的解决方案
嘿,我之前也踩过这个坑!iOS 13 引入的 TabBar 外观系统有个容易忽略的细节——你只更新了 standardAppearance,但系统在某些场景下(比如页面滚动到顶部,TabBar 和导航栏衔接时)会使用 scrollEdgeAppearance,而且有时候直接赋值外观后需要手动触发 TabBar 的布局刷新,不然修改不会立刻生效。
问题根源
iOS 13+ 的 UITabBar 有两个核心外观属性:
standardAppearance:常规状态下的 TabBar 外观scrollEdgeAppearance:当页面内容滚动到边缘(TabBar 与导航栏/状态栏贴合)时使用的外观
你之前的代码只修改了 standardAppearance,如果你的页面支持滚动,或者系统默认触发了 scrollEdgeAppearance 的使用,就会导致修改不生效。另外,有时候即使正确赋值了外观,TabBar 也不会自动刷新布局,需要手动触发。
修复后的代码
把你的 changeTabbarApperence 方法改成这样,同时更新两个外观属性并触发刷新:
@IBAction func changeTabbarApperence(){ guard let tabBar = self.tabBarController?.tabBar else { return } // 复制当前外观并修改 let appearance = tabBar.standardAppearance.copy() appearance.stackedLayoutAppearance.normal.iconColor = .green appearance.stackedLayoutAppearance.normal.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.green] appearance.stackedLayoutAppearance.selected.iconColor = .orange appearance.stackedLayoutAppearance.selected.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.orange] // 同时设置 standard 和 scrollEdge 外观 tabBar.standardAppearance = appearance tabBar.scrollEdgeAppearance = appearance // 手动触发布局刷新,确保修改立刻生效 tabBar.setNeedsLayout() }
初始设置同步修改
为了保证初始状态和切换后的状态逻辑一致,你的 viewDidLoad 里也应该同步设置 scrollEdgeAppearance:
override func viewDidLoad() { super.viewDidLoad() guard let tabBar = self.tabBarController?.tabBar else { return } let appearance = tabBar.standardAppearance.copy() appearance.stackedLayoutAppearance.normal.iconColor = .red appearance.stackedLayoutAppearance.normal.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.red] appearance.stackedLayoutAppearance.selected.iconColor = .blue appearance.stackedLayoutAppearance.selected.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.blue] tabBar.standardAppearance = appearance // 添加这一行,同步初始的 scrollEdge 外观 tabBar.scrollEdgeAppearance = appearance }
额外注意点
- 如果你用的是自定义的
UITabBarController,建议把外观修改的逻辑放在 TabBarController 内部,这样可以更方便地统一管理主题切换。 - 避免强制解包
tabBarController,用可选绑定(guard let)更安全,防止空指针崩溃。
这样修改后,点击按钮切换主题时,TabBar 的图标和标题颜色应该就能正常更新了!
内容的提问来源于stack exchange,提问作者vikas prajapati
相关产品推荐
相关产品推荐

