SwiftUI: 更新导航栏颜色

5

目标:按下按钮时更新导航栏颜色。

当前:导航栏颜色根本不会改变。

尝试:我目前正在使用init()来设置navBarTintColor,我还尝试过这个答案,但都无法按需更新。

代码:

var navColor = Color.green

struct ContentView: View {
    @State var themeColor = Color.green
    @State var items = [0,1,2,3,4,5,6,7,8,9]
    @State var showSheet = false


init() {
    UINavigationBar.appearance().titleTextAttributes = [.foregroundColor: UIColor.black]
    UINavigationBar.appearance().barTintColor = UIColor(navColor)
    UINavigationBar.appearance().backgroundColor = UIColor(navColor)
}

var body: some View {
    NavigationView{
        List{
            ForEach(0..<items.count){ i in
                Text("Item: \(items[i])")
            }.listRowBackground(themeColor)
        }
        .navigationBarTitle("Theme", displayMode: .inline)
        .navigationBarItems(leading: Button(action: {
            showSheet.toggle()
        }, label: {
            Text("Sheet")
        })
        ,trailing: Button(action: {
            self.themeColor = Color(red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1))
            navColor = Color(red: .random(in: 0...1), green: .random(in: 0...1), blue: .random(in: 0...1))
            items.shuffle()
        }, label: {
            Text("Random Color")
            
        }))
//            .background(NavigationConfigurator { nc in
//                nc.navigationBar.barTintColor = UIColor(navColor)
//                nc.navigationBar.titleTextAttributes = [.foregroundColor : UIColor.black]
//            })
        .sheet(isPresented: $showSheet, content: {
            popSheet()
        })
        
    }
}
}

struct popSheet: View {
var body: some View{
    NavigationView{
        Text("Hello")
            .navigationBarTitle("Sheet", displayMode: .inline)
    }
}
}

这里是一个导航配置器,我也尝试使用过。

struct NavigationConfigurator: UIViewControllerRepresentable {
    var configure: (UINavigationController) -> Void = { _ in }
    
    func makeUIViewController(context: UIViewControllerRepresentableContext<NavigationConfigurator>) -> UIViewController {
        UIViewController()
    }
    func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<NavigationConfigurator>) {
        if let nc = uiViewController.navigationController {
            self.configure(nc)
        }
    }
}
1个回答

12
你可以使用.id(themeColor)来强制刷新NavigationView
以下是一种可能的解决方案:
struct ContentView: View {
    @State var themeColor = Color.green
    
    init() {
        updateNavigationBarColor()
    }
    
    var body: some View {
        NavigationView {
            VStack {
                Button("Change to blue") {
                    themeColor = .blue
                    updateNavigationBarColor()
                }
                Button("Change to red") {
                    themeColor = .red
                    updateNavigationBarColor()
                }
            }
            .navigationTitle("Title")
        }
        .id(themeColor)
    }
    
    func updateNavigationBarColor() {
        UINavigationBar.appearance().barTintColor = UIColor(themeColor)
        UINavigationBar.appearance().backgroundColor = UIColor(themeColor)
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接