You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xcode13 iOS15下UINavigationBar不同状态阴影分离显示实现咨询

iOS15 UINavigationBar 自定义阴影切换异常解决方案

问题根因

iOS15 对 UINavigationBar 的渲染逻辑做了两点调整,是导致问题的核心原因:

  • 当 UINavigationBarAppearance 的 shadowColor 属性被显式设置为非 nil 值时,系统会优先使用该颜色渲染阴影,直接忽略自定义的 shadowImage 配置
  • scrollEdgeAppearance 和 standardAppearance 切换时,系统默认仅更新背景色相关属性,不会主动刷新阴影图层,导致自定义阴影不生效

修正方案

1. 修正Appearance配置

核心调整点:需要使用自定义shadowImage时,将shadowColor设为nil,避免覆盖自定义图片的显示。
修正后的完整代码如下:

class MyViewController: UINavigationController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // 全局开启大标题显示
        navigationBar.prefersLargeTitles = true
        
        if #available(iOS 13.0, *) {
            // 标准标题状态配置
            let standard = UINavigationBarAppearance()
            standard.configureWithOpaqueBackground()
            standard.backgroundColor = .systemBlue
            // 替换为你自己的渐变阴影图片即可
            standard.shadowImage = UIImage(color: .black)
            // 关键配置:设置为nil,保证自定义shadowImage生效
            standard.shadowColor = nil
            navigationBar.standardAppearance = standard
            
            // 大标题(滚动边缘)状态配置
            let scroll = UINavigationBarAppearance()
            scroll.configureWithOpaqueBackground()
            scroll.backgroundColor = .systemRed
            // 空图片实现隐藏阴影
            scroll.shadowImage = UIImage()
            scroll.shadowColor = nil
            navigationBar.scrollEdgeAppearance = scroll
            
            // iOS15+ 额外配置,保证紧凑模式、push/pop 时样式一致
            if #available(iOS 15.0, *) {
                navigationBar.compactAppearance = standard
            }
        } else {
            // iOS13以下的兼容逻辑可在此补充
            navigationBar.barTintColor = .systemBlue
            navigationBar.shadowImage = UIImage(color: .black)
        }
    }
}

// 你用到的UIImage扩展,生成纯色图片(仅作示例,可保留你自己的实现)
extension UIImage {
    convenience init(color: UIColor, size: CGSize = CGSize(width: 1, height: 1)) {
        UIGraphicsBeginImageContextWithOptions(size, false, 0)
        color.setFill()
        UIRectFill(CGRect(origin: .zero, size: size))
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        self.init(cgImage: image!.cgImage!)
    }
}

2. 异常情况补充处理

如果按照上述配置后切换状态时阴影仍不刷新,可以在当前页面的UIScrollView代理方法中主动触发导航栏刷新:

// 对应视图控制器中实现scrollView代理方法
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    navigationBar.setNeedsLayout()
    navigationBar.layoutIfNeeded()
}

验证点

  • 标准标题状态下可正常显示自定义渐变阴影图片
  • 大标题状态下阴影完全隐藏
  • iOS14、iOS15+系统表现一致

内容的提问来源于stack exchange,提问作者이동근

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 09:27:06