Swift中iOS13/14下屏幕切换时设置导航栏分隔线颜色的方法?
解决iOS13+导航栏分隔线在多页面共用导航控制器的适配问题
我来帮你搞定这个iOS13及以上版本的导航栏分隔线适配问题!你遇到的核心问题是iOS13之后苹果重构了导航栏的外观管理逻辑,直接设置shadowImage会被UINavigationBarAppearance的配置覆盖,所以得用新的外观API来分别给两个页面做配置。
关键原理
iOS13+中,导航栏的样式由standardAppearance和scrollEdgeAppearance(对应滚动到顶部时的导航栏状态)统一管理,这两个属性的优先级远高于直接设置navigationBar.shadowImage,所以必须通过配置UINavigationBarAppearance来实现不同页面的分隔线需求。
具体实现步骤
首先确保你有生成1pt颜色图片的工具方法(如果还没完善的话):
extension UIColor { func as1ptImage() -> UIImage { UIGraphicsImageRenderer(size: CGSize(width: 1, height: 1)).image { rendererContext in self.setFill() rendererContext.fill(CGRect(x: 0, y: 0, width: 1, height: 1)) } } }
1. 第一个页面(隐藏分隔线)
在页面的viewWillAppear方法中配置导航栏外观,隐藏分隔线:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let appearance = UINavigationBarAppearance() // 用透明图片隐藏分隔线 appearance.shadowImage = UIColor.clear.as1ptImage() // 同步导航栏原有的背景色,避免样式突变 if let navBarBgColor = navigationController?.navigationBar.backgroundColor { appearance.backgroundColor = navBarBgColor } // 必须同时设置两个外观属性,覆盖所有导航栏状态 navigationController?.navigationBar.standardAppearance = appearance navigationController?.navigationBar.scrollEdgeAppearance = appearance }
2. 第二个页面(显示自定义颜色分隔线)
同样在viewWillAppear中配置对应的外观:
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let appearance = UINavigationBarAppearance() // 设置你需要的自定义分隔线颜色 appearance.shadowImage = navBarSeparatorColor.as1ptImage() // 同步背景色保持样式一致 if let navBarBgColor = navigationController?.navigationBar.backgroundColor { appearance.backgroundColor = navBarBgColor } navigationController?.navigationBar.standardAppearance = appearance navigationController?.navigationBar.scrollEdgeAppearance = appearance }
额外注意事项
- 如果你需要保留导航栏的其他样式(比如标题字体、按钮样式),记得在创建
UINavigationBarAppearance时同步配置这些属性,或者基于当前导航栏的外观进行修改(比如let appearance = navigationController?.navigationBar.standardAppearance.copy()),避免样式丢失。 - 确保导航栏的
isTranslucent属性设置符合你的需求,透明导航栏的分隔线显示逻辑和不透明的一致,但如果是半透明状态,可能需要调整背景色的alpha值。
内容的提问来源于stack exchange,提问作者Vyachaslav Gerchicov
相关产品推荐
相关产品推荐

