Skip to content

Instantly share code, notes, and snippets.

@gavinjerman
Last active January 17, 2022 18:06
Show Gist options
  • Save gavinjerman/a862e3dffa03468b8d1a5cf14e1c1f4f to your computer and use it in GitHub Desktop.
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
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