切换SwiftUI中的UINavigationBar外观

切换SwiftUI中的UINavigationBar外观,swiftui,themes,uinavigationbarappearance,Swiftui,Themes,Uinavigationbarappearance,我需要能够根据需要在快捷界面视图中更改颜色。对于视图中的对象,这不是按需切换颜色的问题,但是对于NavigationBar外观属性,如何才能做到这一点呢?下面是初始化视图时如何设置导航栏的外观。点击按钮会更改按钮的颜色,但不会更改导航栏的外观。使用不同的theme1值重新启动应用程序将显示正确的颜色,但点击按钮只会更改按钮的颜色,而不会更改导航栏的外观 struct ContentView: View { @State private var theme1 = true init() {

我需要能够根据需要在快捷界面视图中更改颜色。对于视图中的对象,这不是按需切换颜色的问题,但是对于NavigationBar外观属性,如何才能做到这一点呢?下面是初始化视图时如何设置导航栏的外观。点击按钮会更改按钮的颜色,但不会更改导航栏的外观。使用不同的theme1值重新启动应用程序将显示正确的颜色,但点击按钮只会更改按钮的颜色,而不会更改导航栏的外观

struct ContentView: View {
@State private var theme1 = true
init() {
    let navBarAppearance = UINavigationBarAppearance()
    navBarAppearance.titleTextAttributes = [.foregroundColor: theme1 ? UIColor.red : UIColor.yellow]
    navBarAppearance.largeTitleTextAttributes = [.foregroundColor: theme1 ? UIColor.red : UIColor.yellow]
    navBarAppearance.backgroundColor = theme1 ? UIColor.yellow : UIColor.red
    UINavigationBar.appearance().standardAppearance = navBarAppearance
    UINavigationBar.appearance().compactAppearance = navBarAppearance
    UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance
    UINavigationBar.appearance().tintColor = theme1 ? UIColor.red : UIColor.yellow
}
var body: some View {
    NavigationView {
        VStack {
            Button("Toggle Style") {
                theme1.toggle()
            }
            .padding(8)
            .foregroundColor(theme1 ? Color(.red): Color(.yellow))
            .background(RoundedRectangle(cornerRadius: 10)
                            .fill(theme1 ? Color(.yellow) : Color(.red)))
        }
        .navigationTitle("Theme Picker")
    }
}

}

因为我们在代码中使用UIKit,我们必须先终止View,然后创建我们想要的:


第1版:

import SwiftUI

struct ContentView: View {
    @State private var theme1 = true

    var body: some View {
        
        if theme1 {
            CustomView(theme: $theme1)
        }
        else {
            CustomView(theme: $theme1)
        }
  
    }
}


谢谢事实上,我更喜欢第一种方式,尽管它仍然不理想。非常感谢您花时间给出详细的回复。@StewartLynch:非常欢迎您,我只是推荐了第二种方式,因为它是纯SwiftUI,而且我非常喜欢您的教学风格,我总是向任何要求学习Swift/SwiftUI的人推荐您的youtube频道,所以感谢您的辛勤工作!谢谢你的评论。事实上,我正在编写一个关于在SwiftUI中设置应用程序主题的教程,所以这是缺少的部分之一。当我做视频时,如果你同意的话,我想把这个解决方案归功于你,因为我将要使用它。如果你让我知道你的twitter句柄,我会确保你在视频中得到信任。@StewartLynch:你太好了,我很喜欢看今天关于软件包的视频,我没有与Swift编程相关的twitter,我只是一个有趣的程序员。这是你的决定,无论你是否谈论我,我通过StackOverFlow分享的任何东西都没有复制权或某些东西,但就个人而言,我很高兴听到我的老师告诉我我的名字。如果你认为这会让视频做得更好,否则我也不会漏掉提及。@StewartLynch:我刚才用同样的方式回答了另一个问题:
struct CustomView: View {
    
    @Binding var theme1: Bool
    
    init(theme: Binding<Bool>) {
        
        _theme1 = theme
        
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.titleTextAttributes = [.foregroundColor: theme1 ? UIColor.red : UIColor.yellow]
        navBarAppearance.largeTitleTextAttributes = [.foregroundColor: theme1 ? UIColor.red : UIColor.yellow]
        navBarAppearance.backgroundColor = theme1 ? UIColor.yellow : UIColor.red
        UINavigationBar.appearance().standardAppearance = navBarAppearance
        UINavigationBar.appearance().compactAppearance = navBarAppearance
        UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance
        UINavigationBar.appearance().tintColor = theme1 ? UIColor.red : UIColor.yellow
    }
    
    var body: some View {
        NavigationView {
            VStack {
                Button("Toggle Style") {
                    theme1.toggle()
                }
                .padding(8)
                .foregroundColor(theme1 ? Color(.red): Color(.yellow))
                .background(RoundedRectangle(cornerRadius: 10)
                                .fill(theme1 ? Color(.yellow) : Color(.red)))
            }
            .navigationTitle("Theme Picker")
        }
    }
    
}
import SwiftUI

struct ContentView: View {
    
    @State private var theme1 = true
    
    var body: some View {
        
        NavigationView {
            
            ZStack {
                
                theme1 ? Color.yellow.ignoresSafeArea() : Color.red.ignoresSafeArea()
                
                Color.white.cornerRadius(20).padding()
                
                VStack {
                    
                    Button(action: { theme1.toggle() }, label: {
                        Text("Toggle Style")
                            .bold()
                            .padding(8)
                            .background(theme1 ? Color.yellow : Color.red)
                            .cornerRadius(10)
                    })
                    
                }
                
            }
            
        }
        .overlay(navigationTitle, alignment: .topLeading)
        .foregroundColor(theme1 ? Color.red : Color.yellow)
        .accentColor(theme1 ? Color.red : Color.yellow)
        
    }
    
    var navigationTitle: some View {
        
        return Text("Theme Picker").font(Font.largeTitle.bold()).padding().offset(y: 30)
    }

}