I am currently trying to implement a solution in an app where the user is supposed to be able to switch the app's appearance in real-time with the following options:
- System (applying whatever appearance is set in the iOS settings for the device)
- Light (applying .light color scheme)
- Dark (applying . dark color scheme)
Setting light and dark color schemes has proven to be quite easy and responsive using .preferredColorScheme(); however, I have not yet found any satisfying solution for the "System" option.
My current approach is the following:
- Getting the device color scheme using @Environment(.colorScheme) in ContentView
- Creating a custom view modifier for applying the respective color scheme on whatever view
- Using a modifier on "MainView" (that's where the real content of the app is supposed to live) to switch between the color schemes
My idea was to embed MainView in ContentView so that the @Environment(.colorScheme) would not be disturbed by any colorScheme that is applied to MainView.
However, it still doesn't work as supposed: When setting light and dark appearance, everything works as intended. However, when switching from light/dark to "system", the change in appearance is only visible after re-launching the app. Expected behavior, however, would be that the appearance changes instantly.
Any ideas on this?
Here are the relevant code snippets:
Main view
import SwiftUI struct MainView: View { @EnvironmentObject var settings: UserSettings @AppStorage("selectedAppearance") var selectedAppearance = 0 var body: some View { VStack { Spacer() Button(action: { selectedAppearance = 1 }) { Text("Light") } Spacer() Button(action: { selectedAppearance = 2 }) { Text("Dark") } Spacer() Button(action: { selectedAppearance = 0 }) { Text("System") } Spacer() } } }
ContentView
import SwiftUI struct ContentView: View { @Environment(\.colorScheme) var colorScheme @EnvironmentObject var settings: UserSettings var body: some View { MainView() .modifier(ColorSchemeModifier(colorScheme: colorScheme)) .environmentObject(settings) } }
"Utilities"
import Foundation import SwiftUI class UserSettings: ObservableObject { @Published var colorSchemeShow: ColorScheme = .light } struct ColorSchemeModifier: ViewModifier { @AppStorage("selectedAppearance") var selectedAppearance: Int = 0 var colorScheme: ColorScheme func body(content: Content) -> some View { if selectedAppearance == 2 { return content.preferredColorScheme(.dark) } else if selectedAppearance == 1 { return content.preferredColorScheme(.light) } else { return content.preferredColorScheme(colorScheme) } } }
https://stackoverflow.com/questions/65798263/swiftui-how-to-let-the-user-set-the-app-appearance-in-real-time-w-options-lig January 20, 2021 at 03:31AM
没有评论:
发表评论