Last active
January 17, 2022 18:06
-
-
Save gavinjerman/a862e3dffa03468b8d1a5cf14e1c1f4f to your computer and use it in GitHub Desktop.
Example code showing how to set color scheme in SwiftUI app using code from https://github.com/writefreely/writefreely-swiftui-multiplatform
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
@main | |
struct testColorSchemeApp: App { | |
@StateObject private var appearanceManager = AppearanceManager() | |
var body: some Scene { | |
WindowGroup { | |
ContentView() | |
.environmentObject(appearanceManager) | |
.onAppear { | |
appearanceManager.setAppearance() | |
} | |
} | |
} | |
} | |
struct ContentView: View { | |
@EnvironmentObject var appearanceManager: AppearanceManager | |
var body: some View { | |
NavigationView { | |
List { | |
Section(header: Text("Appearance")) { | |
Button { | |
appearanceManager.appearance = .system | |
} label: { | |
AppearanceOption(appearance: .system) | |
} | |
Button { | |
appearanceManager.appearance = .light | |
} label: { | |
AppearanceOption(appearance: .light) | |
} | |
Button { | |
appearanceManager.appearance = .dark | |
} label: { | |
AppearanceOption(appearance: .dark) | |
} | |
} | |
} | |
.navigationTitle("Color Scheme") | |
} | |
} | |
} | |
struct AppearanceOption: View { | |
@EnvironmentObject var appearanceManager: AppearanceManager | |
var appearance: AppearanceManager.Appearance | |
var body: some View { | |
HStack { | |
Text(appearance.rawValue.capitalized) | |
Spacer() | |
if appearanceManager.appearance == appearance { | |
Image(systemName: "checkmark") | |
} | |
} | |
} | |
} | |
class AppearanceManager: ObservableObject { | |
@AppStorage("appearance") var appearance: Appearance = .system { // default appearance is .system | |
didSet { | |
setAppearance() | |
} | |
} | |
enum Appearance: String { | |
case light | |
case dark | |
case system | |
} | |
func setAppearance() { | |
switch appearance { | |
case .light: | |
window?.overrideUserInterfaceStyle = .light | |
case .dark: | |
window?.overrideUserInterfaceStyle = .dark | |
case .system: | |
window?.overrideUserInterfaceStyle = .unspecified | |
} | |
} | |
// https://github.com/writefreely/writefreely-swiftui-multiplatform/blob/main/Shared/Preferences/PreferencesModel.swift | |
/* We're stuck dropping into AppKit/UIKit to set light/dark schemes for now, | |
* because setting the .preferredColorScheme modifier on views in SwiftUI is | |
* currently unreliable. | |
* | |
* Feedback submitted to Apple: | |
* | |
* FB8382883: "On macOS 11β4, preferredColorScheme modifier does not respect .light ColorScheme" | |
* FB8383053: "On iOS 14β4/macOS 11β4, it is not possible to unset preferredColorScheme after setting | |
* it to either .light or .dark" | |
*/ | |
private var window: UIWindow? { | |
guard let scene = UIApplication.shared.connectedScenes.first, | |
let windowSceneDelegate = scene.delegate as? UIWindowSceneDelegate, | |
let window = windowSceneDelegate.window else { | |
return nil | |
} | |
return window | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment