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

SwiftUI中如何动态修改并更新NavigationBar的背景颜色

问题原因

你当前的代码仅在视图初始化时执行了一次全局UINavigationBar外观配置,已渲染完成的导航栏不会响应全局外观的后续变更,且@State属性color更新时不会重新触发视图的init方法,因此背景色无法同步更新。


解决方案

方案1:iOS 16+ 原生SwiftUI实现(推荐)

iOS 16新增了原生的导航栏背景配置 modifier,无需桥接UIKit即可实现动态更新和过渡动画:

struct ContentView: View {
    @State var color: Color = .red
    
    var body: some View {
        NavigationStack { // iOS16起推荐用NavigationStack替代废弃的NavigationView
            VStack(spacing: 20) {
                Button(action: {
                    withAnimation { // 加这个即可实现颜色过渡动画
                        color = .blue
                    }
                }) {
                    Text("Blue")
                        .font(.title)
                        .bold()
                        .foregroundColor(.white)
                        .frame(width: 100)
                        .padding()
                        .background(Color.blue)
                        .cornerRadius(15)
                }
                Button(action: {
                    withAnimation {
                        color = .red
                    }
                }) {
                    Text("Red")
                        .font(.title)
                        .bold()
                        .foregroundColor(.white)
                        .frame(width: 100)
                        .padding()
                        .background(Color.red)
                        .cornerRadius(15)
                }
            }
            .offset(y: -50)
            .navigationTitle("My Navigation")
            .toolbarColorScheme(.dark, for: .navigationBar) // 配置导航栏标题为白色
            .toolbarBackground(color, for: .navigationBar) // 动态绑定背景色
            .toolbarBackground(.visible, for: .navigationBar) // 强制显示背景,避免滚动时隐藏
        }
    }
}

方案2:兼容iOS 13+ 桥接UIKit实现

如果需要兼容更低版本系统,可以通过监听color变更,主动更新当前导航栏的外观:

struct ContentView: View {
    @State var color: Color = .red
    
    init() {
        updateNavBarAppearance(color: color)
    }
    
    // 抽离导航栏配置方法
    private func updateNavBarAppearance(color: Color) {
        let navbarAppearance = UINavigationBarAppearance()
        navbarAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
        navbarAppearance.titleTextAttributes = [.foregroundColor: UIColor.white]
        navbarAppearance.backgroundColor = UIColor(color)
        UINavigationBar.appearance().standardAppearance = navbarAppearance
        UINavigationBar.appearance().compactAppearance = navbarAppearance
        UINavigationBar.appearance().scrollEdgeAppearance = navbarAppearance
    }
    
    var body: some View {
        NavigationView {
            VStack(spacing: 20) {
                Button(action: {
                    UIView.animate(withDuration: 0.3) { // 加动画实现平滑过渡
                        color = .blue
                    }
                }) {
                    Text("Blue")
                        .font(.title)
                        .bold()
                        .foregroundColor(.white)
                        .frame(width: 100)
                        .padding()
                        .background(Color.blue)
                        .cornerRadius(15)
                }
                Button(action: {
                    UIView.animate(withDuration: 0.3) {
                        color = .red
                    }
                }) {
                    Text("Red")
                        .font(.title)
                        .bold()
                        .foregroundColor(.white)
                        .frame(width: 100)
                        .padding()
                        .background(Color.red)
                        .cornerRadius(15)
                }
            }
            .offset(y: -50)
            .navigationTitle("My Navigation")
            // 监听color变更,触发更新
            .onChange(of: color) { newColor in
                updateNavBarAppearance(color: newColor)
                // 主动刷新当前导航栏
                UINavigationBar.appearance().setNeedsLayout()
                UINavigationBar.appearance().layoutIfNeeded()
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 09:09:03