简体   繁体   中英

SwiftUI Dark theme toggle doesn't change child view color

I am trying to create a dark theme toggle and another toggle to follow the system theme. When I change either of these two toggles in my settings menu, I change the preferred color scheme of the app in ContentView.

However, the current settings sheet is not changing color when I change the toggle state. When I dismiss and reopen the settings sheet, the color changes, but I don't want to trigger a dismiss every time the theming switch is toggled.

How would I change the color of the current settings sheet AND the app's preferred color scheme when the switch is toggled?

Any help is appreciated.

My code is pasted down below, tested on MacCatalyst and iOS:

struct ContentView: View {
    @AppStorage("useDarkTheme") var useDarkTheme = false
    @AppStorage("followSystemTheme") var followSystemTheme = false
    
    @State var showSheet: Bool = false

    var body: some View {
        VStack {
            Text("Hello")
            
            Button("Open sheet") {
                showSheet.toggle()
            }
            .sheet(isPresented: $showSheet) {
                InnerView()
            }
        }
        .preferredColorScheme(followSystemTheme ? nil : (useDarkTheme ? .dark : .light))
    }
}

struct InnerView: View {
    @AppStorage("useDarkTheme") var useDarkTheme = false
    @AppStorage("followSystemTheme") var followSystemTheme = false
    
    @Environment(\.presentationMode) var presentationMode
    
    var body: some View {
        Form {
            Section(header: Text("Theme")) {
                Toggle(isOn: $useDarkTheme) {
                    Text("Use dark theme")
                }
                
                Toggle(isOn: $followSystemTheme) {
                    Text("Follow system theme")
                }
            }
        }
        
        Button("Dismiss") {
            presentationMode.wrappedValue.dismiss()
        }
    }
}

Here is the fix, sheet is not in same hierarchy, therefore you should apply it:

struct ContentView: View {
    @AppStorage("useDarkTheme") var useDarkTheme = false
    @AppStorage("followSystemTheme") var followSystemTheme = false
    
    @State var showSheet: Bool = false

    var body: some View {
        VStack {
            Text("Hello")
            
            Button("Open sheet") {
                showSheet.toggle()
            }
            .sheet(isPresented: $showSheet) {
                InnerView()
                    .preferredColorScheme(followSystemTheme ? nil : (useDarkTheme ? .dark : .light)) // <<: Here!
                   
            }
        }
        .preferredColorScheme(followSystemTheme ? nil : (useDarkTheme ? .dark : .light))
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM