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

iOS返回根视图控制器时Large Navigation Bar背景变透明问题

解决Large Navigation Bar滑动返回时背景变透明的问题

看起来你遇到的这个问题在iOS 11+的大标题导航栏场景里挺常见的,主要是大标题导航栏的内部视图层级和过渡动画特性导致的,直接设置backgroundColor有时候会在滑动返回过程中失效。我来帮你分析下原因和对应的解决方案:

可能的问题根源

  • iOS 11+的大标题导航栏(开启prefersLargeTitles = true)有独立的背景视图层级,直接设置navigationBar.backgroundColor在过渡动画时无法稳定维持状态
  • 导航栏默认的isTranslucent属性为true,半透明状态下滑动时会和底层视图混合,视觉上呈现出背景变透明的效果
  • 设置时机的覆盖不足,仅在viewWillAppear和viewDidLoad设置,没覆盖到过渡动画过程中的状态变化

具体解决方案

1. 改用官方推荐的barTintColor设置背景色

UIKit专门为导航栏设计了barTintColor属性来设置背景色,相比直接设置backgroundColor,它能更好地适配大标题导航栏的视图层级:

func largeNavigationTitle() {
    // 统一导航控制器view的背景色,避免滑动时露出底层违和颜色
    self.navigationController?.view.backgroundColor = VVUtility.splashBackGroundColor()
    
    let productTitle = request?.product?.name
    self.navigationItem.title = "\(productTitle ?? " ")".localized()
    
    // 设置普通标题的文字属性
    self.navigationController?.navigationBar.titleTextAttributes = [
        NSAttributedString.Key.foregroundColor : UIColor.white,
        NSAttributedString.Key.font : VVUtility.normalFontWithPlusSize(increaseSize: -2.0)
    ]
    
    if #available(iOS 11.0, *) {
        self.navigationController?.navigationBar.prefersLargeTitles = true
        // 替换为barTintColor设置背景色
        self.navigationController?.navigationBar.barTintColor = VVUtility.splashBackGroundColor()
        // 禁用半透明,避免过渡时的视图混合问题
        self.navigationController?.navigationBar.isTranslucent = false
        
        self.navigationController?.navigationBar.largeTitleTextAttributes = [
            NSAttributedString.Key.foregroundColor : UIColor.white,
            NSAttributedString.Key.font : VVUtility.normalFontWithPlusSize(increaseSize: 0.0)
        ]
    } else {
        // iOS 11以下的兼容设置
        self.navigationController?.navigationBar.barTintColor = VVUtility.splashBackGroundColor()
        self.navigationController?.navigationBar.isTranslucent = false
    }
}

2. 可选:在viewWillDisappear中巩固状态

如果滑动返回时仍有异常,可以在当前视图控制器的viewWillDisappear中再次确认导航栏设置,避免返回时状态被重置:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    let bgColor = VVUtility.splashBackGroundColor()
    self.navigationController?.navigationBar.barTintColor = bgColor
    self.navigationController?.navigationBar.isTranslucent = false
}

3. 可选:全局统一导航栏样式

如果APP内多个页面都使用大标题导航栏,可以在App启动时全局设置,避免重复设置导致的状态不一致:

// 在AppDelegate或SceneDelegate的启动方法中添加
UINavigationBar.appearance().barTintColor = VVUtility.splashBackGroundColor()
UINavigationBar.appearance().isTranslucent = false

if #available(iOS 11.0, *) {
    UINavigationBar.appearance().prefersLargeTitles = true
    UINavigationBar.appearance().largeTitleTextAttributes = [
        NSAttributedString.Key.foregroundColor : UIColor.white,
        NSAttributedString.Key.font : VVUtility.normalFontWithPlusSize(increaseSize: 0.0)
    ]
}

UINavigationBar.appearance().titleTextAttributes = [
    NSAttributedString.Key.foregroundColor : UIColor.white,
    NSAttributedString.Key.font : VVUtility.normalFontWithPlusSize(increaseSize: -2.0)
]

方案说明

  • barTintColor会正确作用于导航栏的所有背景视图层级,包括大标题模式下的扩展背景区域,避免过渡动画中的状态丢失
  • 禁用isTranslucent后,导航栏完全不透明,滑动时不会和底层视图混合,彻底解决背景变透明的视觉问题
  • 统一导航控制器view的背景色,就算过渡时导航栏有短暂层级变化,底层颜色也和导航栏一致,不会露出违和的色块

你可以先尝试第一种方案,应该就能解决滑动返回时背景变透明的问题了。

内容的提问来源于stack exchange,提问作者Omid Kia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:22:05