Swift:能否仅为导航层级中单个ViewController设置导航栏颜色?
解决导航栏返回后颜色不恢复的问题
嗨,我之前也碰到过一模一样的问题!你遇到的这个导航栏颜色回不去的情况,大概率是因为直接修改了导航栏的全局属性,而且没在合适的时机重置样式。下面给你几个靠谱的解决办法:
方法一:利用ViewController生命周期方法(最稳妥)
这个方法的核心是让每个页面在显示时设置自己需要的导航栏样式,离开时重置为默认值,双重保险:
- 先给所有ViewController创建一个父类(比如
BaseViewController),在里面统一设置默认的红色导航栏:
class BaseViewController: UIViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 设置默认导航栏背景色 navigationController?.navigationBar.barTintColor = .red // 如果需要统一标题颜色,也可以在这里设置 navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white] } }
- 让你的所有页面都继承这个
BaseViewController,然后在最后那个需要蓝色导航栏的页面里,重写两个生命周期方法:
class BlueViewController: BaseViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) // 覆盖父类的设置,改成蓝色 navigationController?.navigationBar.barTintColor = .blue } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // 页面消失时重置为红色,确保返回上一页时导航栏恢复默认 navigationController?.navigationBar.barTintColor = .red } }
这样不管是点击返回按钮还是侧滑返回,只要当前页面消失,导航栏颜色就会被重置,返回上一页时父类的viewWillAppear还会再设置一次红色,完全不用担心样式残留。
方法二:使用UINavigationBarAppearance(iOS13+ 推荐的现代方案)
如果你的APP只适配iOS13及以上版本,更推荐用UINavigationBarAppearance来管理样式,它不会互相干扰,每个页面可以独立设置自己的导航栏外观:
- 在
BaseViewController里设置默认的红色外观:
class BaseViewController: UIViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let redAppearance = UINavigationBarAppearance() redAppearance.backgroundColor = .red redAppearance.titleTextAttributes = [.foregroundColor: UIColor.white] // 应用到导航栏的两种状态(普通状态和滚动到顶部的状态) navigationController?.navigationBar.standardAppearance = redAppearance navigationController?.navigationBar.scrollEdgeAppearance = redAppearance } }
- 在蓝色页面里设置专属的蓝色外观,并在消失时重置:
class BlueViewController: BaseViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let blueAppearance = UINavigationBarAppearance() blueAppearance.backgroundColor = .blue blueAppearance.titleTextAttributes = [.foregroundColor: UIColor.white] navigationController?.navigationBar.standardAppearance = blueAppearance navigationController?.navigationBar.scrollEdgeAppearance = blueAppearance } override func viewWillDisappear(_ animated: Bool) { super.viewWillDisappear(animated) // 回到默认的红色外观 let redAppearance = UINavigationBarAppearance() redAppearance.backgroundColor = .red redAppearance.titleTextAttributes = [.foregroundColor: UIColor.white] navigationController?.navigationBar.standardAppearance = redAppearance navigationController?.navigationBar.scrollEdgeAppearance = redAppearance } }
你之前改回去没用很可能是因为用了UINavigationBarAppearance之后,直接修改barTintColor已经不生效了,必须更新Appearance对象才能改变样式。
为什么之前的修改没效果?
总结一下常见的原因:
- 直接修改了
UINavigationBar的全局属性,没有在返回时重新覆盖; - 用了iOS13+的
UINavigationBarAppearance,但后续修改barTintColor没有更新Appearance对象; - 没有在正确的生命周期方法里设置样式(比如用
viewDidLoad而不是viewWillAppear,导致页面显示时没有重新触发样式设置)。
内容的提问来源于stack exchange,提问作者pmax1
相关产品推荐
相关产品推荐

