iOS中如何实现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
相关产品推荐
相关产品推荐

