苹果之前在iOS 13中为UINavigationBar增加了scrollEdgeAppearance属性,用在iOS 14及更早版本的大标题导航栏上,但是在iOS 15中scrollEdgeAppearance属性适用于所有的导航栏。
配置导航栏颜色、分割线、阴影的常用属性涉及到:
backgroundColor -背景色,位于backgroundImage之下
backgroundImage -背景图片
backgroundEffect -基于backgroundColor或backgroundImage的磨砂效果
backgroundImageContentMode -渲染backgroundImage时的内容模式。 默认为UIViewContentModeScaleToFill
shadowColor -阴影颜色 当shadowImage为nil时,使用此颜色为阴影色。如果此属性为nil或clearColor,则不显示阴影。
shadowImage -阴影图片(可以使用图片的渲染模式:UIImageRenderingModeAlwaysOriginal 保持原色)
导航栏设置
/// 配置导航栏外观样式(兼容iOS 13+和旧版本)
///
/// 此方法提供统一的导航栏样式配置接口,自动处理不同iOS版本的适配问题。
/// 对于iOS 13+使用UINavigationBarAppearance API,旧版本使用传统配置方式。
///
/// - Parameters:
/// - titleColor: 导航栏标题文字颜色,默认黑色
/// - tintColor: 导航栏按钮(返回按钮等)颜色,默认黑色
/// - barTintColor: 导航栏背景颜色,默认浅灰色。当isTransparent为true时此参数无效
/// - hideShadowLine: 是否隐藏导航栏底部阴影分隔线,默认false显示
/// - isTransparent: 是否设置导航栏为透明,默认false不透明。设为true时会覆盖barTintColor设置
@objc func setupNavigationBar(titleColor: UIColor = kColor.black,
tintColor: UIColor = kColor.black,
barTintColor: UIColor = kColor.bgGray,
hideShadowLine: Bool = false,
isTransparent: Bool = false) {
// 安全获取导航栏引用,避免强制解包
guard let navigationBar = navigationController?.navigationBar else {
return
}
// ========== iOS 13+ 现代配置方式 ==========
if #available(iOS 13.0, *) {
let appearance = UINavigationBarAppearance()
// 背景配置
if isTransparent {
// 透明背景配置
appearance.configureWithTransparentBackground()
appearance.backgroundEffect = nil // 移除默认的模糊效果
} else {
// 不透明背景配置
appearance.configureWithOpaqueBackground()
appearance.backgroundColor = barTintColor
}
// 阴影线配置(iOS 13+使用shadowColor替代原来的shadowImage)
appearance.shadowColor = hideShadowLine ? .clear : .rgba(216, 216, 216, 1)
// 标题文本属性配置
appearance.titleTextAttributes = [
.foregroundColor: titleColor,
// 可在此处添加其他文本属性如字体等
// .font: UIFont.systemFont(ofSize: 17, weight: .semibold)
]
// 应用配置到所有可能的导航栏状态
navigationBar.standardAppearance = appearance // 标准高度导航栏
navigationBar.scrollEdgeAppearance = appearance // 大标题导航栏
navigationBar.compactAppearance = appearance // 紧凑高度导航栏(iPhone横屏等情况)
// 修复iOS 15滚动时导航栏过渡动画问题
navigationBar.setNeedsLayout()
}
// ========== iOS 12及以下传统配置方式 ==========
else {
// 设置标题颜色
navigationBar.titleTextAttributes = [.foregroundColor: titleColor]
// 设置按钮颜色
navigationBar.tintColor = tintColor
if isTransparent {
// 透明导航栏配置
navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationBar.shadowImage = UIImage() // 同时移除阴影线
navigationBar.isTranslucent = true
} else {
// 不透明导航栏配置
navigationBar.barTintColor = barTintColor
navigationBar.isTranslucent = false
navigationBar.shadowImage = hideShadowLine ? UIImage() : nil
}
}
// 公共配置(所有iOS版本通用)
navigationBar.tintColor = tintColor // 确保按钮颜色设置
// 立即应用布局更改
DispatchQueue.main.async {
navigationBar.layoutIfNeeded()
}
}