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

iOS中如何实现UINavigationBar颜色的平滑过渡效果?

UINavigationBar 平滑透明过渡完整实现方案

嗨,我来帮你把这个导航栏平滑过渡的效果彻底搞定!你当前的思路是对的,不过代码还没写完,而且得考虑返回页面时的样式恢复问题,我来补全并优化一下~

下面是完整的可运行代码,还加了关键细节的说明:

class ChildViewController: UIViewController {
    // 保存导航栏原始样式,用于离开页面时恢复
    private var originalNavBarBackground: UIImage?
    private var originalNavBarShadow: UIImage?
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        guard let navBar = navigationController?.navigationBar else { return }
        // 先存好原始样式,避免返回时导航栏样式混乱
        originalNavBarBackground = navBar.backgroundImage(for: .default)
        originalNavBarShadow = navBar.shadowImage
        
        // 执行平滑过渡动画,把时长调到0.3更符合iOS系统的自然节奏
        UIView.animate(withDuration: 0.3) {
            navBar.setBackgroundImage(UIImage(), for: .default)
            navBar.shadowImage = UIImage()
            // 如果导航栏透明后,标题和按钮颜色需要切换(比如从黑变白),也放在动画里同步变化
            navBar.titleTextAttributes = [.foregroundColor: UIColor.white]
            navBar.tintColor = .white
        }
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        
        guard let navBar = navigationController?.navigationBar,
              let originalBg = originalNavBarBackground,
              let originalShadow = originalNavBarShadow else { return }
        
        // 离开页面时平滑恢复导航栏原始样式
        UIView.animate(withDuration: 0.3) {
            navBar.setBackgroundImage(originalBg, for: .default)
            navBar.shadowImage = originalShadow
            // 同步恢复标题和按钮颜色
            navBar.titleTextAttributes = [.foregroundColor: UIColor.black]
            navBar.tintColor = .black
        }
    }
}

关键细节提醒

  • 必须保存原始样式:如果不存父页面的导航栏样式,返回时会导致导航栏一直保持透明,破坏页面间的样式一致性。
  • 动画时长适配:0.1秒的动画太快,用户几乎感知不到,改成0.3秒更贴近iOS系统自带的过渡速度,体验更自然。
  • 颜色同步过渡:导航栏变透明后,标题和按钮如果还是深色,会和背景融合看不清,所以要把颜色调整逻辑也放进动画闭包里,确保透明度和颜色变化同步完成。
  • 滚动渐变扩展(可选):如果需要配合滚动视图(比如UITableView)实现滚动时的渐变效果,可以在scrollViewDidScroll方法里动态计算透明度:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let offsetY = scrollView.contentOffset.y
    // 60是导航栏默认高度,可根据需求调整渐变的触发阈值
    let alpha = min(max(offsetY / 60, 0), 1)
    navigationController?.navigationBar.backgroundColor = UIColor.systemBackground.withAlphaComponent(alpha)
    // 同步调整标题颜色的透明度或色值
}

注意:用backgroundColor调整透明度时,要把setBackgroundImage设为nil,两种方式不要混用,否则会出现样式冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:15:35