iOS Swift开发中NavigationBar颜色修改失效问题求解
iOS导航栏配置失效问题修复
问题说明
需要实现的导航栏效果:
- 顶部展示当前ViewController的名称
- 导航栏右侧放置标注「Log Out」的操作按钮
实际运行异常表现: - 所有修改导航栏颜色的代码均不生效,导航栏呈深黑色
- 导航栏上不显示任何文本内容
先后尝试的无效代码:
- 直接修改当前导航栏实例属性
self.navigationController?.navigationBar.isTranslucent = false self.navigationController?.navigationBar.barTintColor = .red self.navigationController?.navigationBar.tintColor = .red
- 全局appearance旧API配置
UINavigationBar.appearance().barTintColor = UIColor(red: 100, green: 186, blue: 44, alpha: 1) UINavigationBar.appearance().isTranslucent = false
- iOS13+ UINavigationBarAppearance 全局配置
let appearance = UINavigationBarAppearance() appearance.configureWithOpaqueBackground() appearance.titleTextAttributes = [.foregroundColor: UIColor.black] appearance.shadowColor = .clear appearance.shadowImage = nil appearance.backgroundColor = UIColor(red: 100.0/255.0, green: 186.0/255.0, blue: 44.0/255.0, alpha: 1.0) UINavigationBar.appearance().tintColor = .black UINavigationBar.appearance().standardAppearance = appearance UINavigationBar.appearance().compactAppearance = appearance UINavigationBar.appearance().scrollEdgeAppearance = appearance if #available(iOS 15.0, *) { UINavigationBar.appearance().compactScrollEdgeAppearance = appearance }
代码失效核心原因
- 色值写法错误:
UIColor的RGB初始化参数取值范围为01,直接传入0255区间的整数会导致颜色计算结果严重偏暗,接近黑色。 - 配置时机错误:全局
appearance配置仅对后续初始化的导航栏实例生效,如果在导航栏已经渲染完成后再修改appearance属性,不会作用于现有实例;如果当前控制器没有被正确嵌入UINavigationController,所有通过self.navigationController调用的属性修改代码都不会执行。 - 系统样式覆盖:iOS13之后系统支持动态暗黑模式,旧版
barTintColorAPI会被系统默认动态样式覆盖,必须搭配UINavigationBarAppearance才能固定样式。 - 配置作用域错误:仅配置全局appearance但没有给当前已存在的导航栏实例赋值appearance属性,导致当前页面导航栏样式没有被更新。
可直接生效的实现方案
- 基础检查
确保当前ViewController是被UINavigationController管理的,可以在viewDidLoad中打印self.navigationController确认其不为nil。 - 当前页面导航栏配置
在当前控制器的viewDidLoad方法中添加以下代码:
// 设置页面标题 self.title = "当前页面名称" // 配置右侧Log Out按钮 let logoutItem = UIBarButtonItem(title: "Log Out", style: .plain, target: self, action: #selector(handleLogout)) self.navigationItem.rightBarButtonItem = logoutItem // 导航栏样式配置 if #available(iOS 13.0, *) { let barAppearance = UINavigationBarAppearance() barAppearance.configureWithOpaqueBackground() // 自定义导航栏背景色,注意色值要除以255映射到0~1区间 barAppearance.backgroundColor = UIColor(red: 100.0/255.0, green: 186.0/255.0, blue: 44.0/255.0, alpha: 1.0) // 标题文字样式 barAppearance.titleTextAttributes = [.foregroundColor: UIColor.black] // 隐藏导航栏底部默认阴影线 barAppearance.shadowColor = .clear // 给当前导航栏实例设置所有状态下的样式 self.navigationController?.navigationBar.standardAppearance = barAppearance self.navigationController?.navigationBar.scrollEdgeAppearance = barAppearance self.navigationController?.navigationBar.compactAppearance = barAppearance if #available(iOS 15.0, *) { self.navigationController?.navigationBar.compactScrollEdgeAppearance = barAppearance } // 设置导航栏按钮颜色 self.navigationController?.navigationBar.tintColor = .black self.navigationController?.navigationBar.isTranslucent = false } else { // iOS13以下版本兼容 self.navigationController?.navigationBar.barTintColor = UIColor(red: 100.0/255.0, green: 186.0/255.0, blue: 44.0/255.0, alpha: 1.0) self.navigationController?.navigationBar.tintColor = .black self.navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.black] self.navigationController?.navigationBar.isTranslucent = false } // Log Out按钮点击逻辑 @objc private func handleLogout() { // 写入登出业务逻辑 }
- 全局样式配置(可选)
如果需要App内所有导航栏统一样式,把上述UINavigationBarAppearance相关的配置代码移到AppDelegate的application(_:didFinishLaunchingWithOptions:)方法中,在window和根导航控制器初始化之前,通过UINavigationBar.appearance()设置全局样式即可。
内容的提问来源于stack exchange,提问作者Dylon Jaynes
相关产品推荐
相关产品推荐

