iOS15导航栏适配

苹果之前在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()
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容