Created
April 12, 2023 11:23
SwiftUI App Theme Picker
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
// | |
// AppThemePicker.swift | |
// AppThemePicker | |
// | |
// Created by Ben Brackenbury on 12/04/2023. | |
// | |
import SwiftUI | |
//MARK: - Picker View | |
/** | |
A Picker controler to an ``AppTheme``. | |
Requires the ``UsePreferedTheme`` modifer to be applied to views that you wish this preference to be applied to. | |
Usually, you want to apply this to your app's entry point. | |
For example: | |
``` | |
@main | |
struct MyApp: App { | |
var body: some Scene { | |
WindowGroup { | |
ContentView() | |
.usePreferredTheme() | |
} | |
} | |
} | |
``` | |
- Author: Ben Brackenbury | |
*/ | |
struct AppThemePicker: View { | |
@AppStorage("appTheme") var appTheme: AppTheme = .system | |
var body: some View { | |
Picker("Theme", selection: $appTheme) { | |
ForEach(AppTheme.allCases) { theme in | |
Text(theme.rawValue).tag(theme) | |
} | |
} | |
} | |
} | |
struct AppThemePicker_Previews: PreviewProvider { | |
static var previews: some View { | |
AppThemePicker() | |
} | |
} | |
//MARK: - AppTheme Enum | |
/** | |
Represents themes for the app | |
- System | |
- Light | |
- Dark | |
- Author: Ben Brackenbury | |
*/ | |
enum AppTheme: String, CaseIterable, Identifiable, Codable { | |
var id: UUID { UUID() } | |
case system = "System" | |
case light = "Light" | |
case dark = "Dark" | |
} | |
//MARK: - UsePreferedTheme custom View modifier | |
/** | |
View Modifier to apply *prefersColorScheme()* to a view | |
- Author: Ben Brackenbury | |
*/ | |
fileprivate struct UsePreferedTheme: ViewModifier { | |
/** | |
Persistent ``AppTheme`` property which determines the | |
app to use | |
*/ | |
@AppStorage("appTheme") var theme: AppTheme = .system | |
func body(content: Content) -> some View { | |
content | |
.preferredColorScheme(theme == .system ? .none : (theme == .light) ? .light : .dark) | |
} | |
} | |
extension View { | |
/** | |
Applies the ``UsePreferedTheme`` modifier to a ``View`` | |
- Author: Ben Brackenbury | |
*/ | |
func usePreferredTheme() -> some View { | |
modifier(UsePreferedTheme()) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment