How to change the App Theme

I’m currently developing an App, and I aim to realize multiple theme colors. Users will have the option to switch between themes such as red, orange, blue and others. Therefore, I’m documenting how this functionality is implemented here.

demo

First, let’s take a look at the demo to see the visual effects. Here, I’ve created a demo where clicking on different themes will cause the app to change its theme color accordingly.

Theme Color

demo

Theme Code

TaoAppTheme

First, define an enum Theme (I did use the name: TaoAppTheme) and implement some methods inside:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import Foundation
import SwiftUI

enum TaoAppTheme: String, CaseIterable, Identifiable {
    
    var id: Self {self}
    
    case App_Theme_orange   = "yellow"
    case App_Theme_green    = "green"
    case App_Theme_blue     = "blue"
    case App_Theme_cyan     = "cyan"
    case App_Theme_red      = "red"
    
    /// Haupt-Hintergrundfarbe
    static func bgPrimaryWhite() -> Color {
        return Color("BgWhite")
    }
    
    //
    static func bgPrimaryGray() -> Color {
        return Color("BgGray")
    }
    
    var color: Color {
        return themeColor()
    }
    
    func themeColor() -> Color {
        switch self {
        case .App_Theme_orange:
            return Color("AppOrange")
        case .App_Theme_green:
            return Color("AppGreen")
        case .App_Theme_blue:
            return Color("AppBlue")
        case .App_Theme_cyan:
            return Color("AppCyan")
        case .App_Theme_red:
            return Color("AppRed")
        }
    }
    
    
    static func nowTheme() -> TaoAppTheme {
        guard let theme:String = UserDefaults.standard.string(forKey: "TaoAppThemeKey") else{
            return .App_Theme_blue
        }
        guard let nowThemeType = TaoAppTheme(rawValue: theme) else{
            return .App_Theme_blue
        }
        return nowThemeType
    }
}

TaoAppState

Then, define an AppState to store the state values of the app.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
import Foundation
import SwiftUI

final class TaoAppState: ObservableObject {
    @Published var appTheme: TaoAppTheme = .App_Theme_blue
    
    init() {
        // das Thema erhalten
        appTheme = TaoAppTheme.nowTheme()
    }
    
    func setTheme(theme: TaoAppTheme){
        UserDefaults.standard.setValue(theme.rawValue, forKey: "TaoAppThemeKey")
        self.appTheme = theme
        print("theme: \(theme.rawValue)")
    }
}

XXXApp.swift

Finally, inject it at the entry(@main) point of the app.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@main
struct DoBillApp: App {
    
        @StateObject private var appState = TaoAppState()
        var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(appState)
        }
    }
}

Employ

1
@EnvironmentObject var appState:APPState

View’s Theme

1
2
Rectangle()
	.foregroundStyle(appState.appTheme.themeColor())

Click Button to change Theme

1
2
3
4
5
6
Button(action: {
	//appState.setTheme(theme: theme)
	appState.setTheme(theme: . App_Theme_orange)              
}, label: {
	Text("Change Theme")
})

Demo View

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import SwiftUI

struct TaoHomeView: View {
    @EnvironmentObject var appState: TaoAppState
    
    @State private var themeIndex = 0
    
    var body: some View {
        VStack {
            
            ForEach(TaoAppTheme.allCases) { theme in
                Button(action: {
                    appState.setTheme(theme: theme)
                    
                }, label: {
                    Text("Change Theme: \(theme.rawValue)")
                })
                .buttonStyle(.borderedProminent)
                .buttonBorderShape(.capsule)
                .controlSize(.large)
                .tint(theme.color)
            }
            
            
            Rectangle()
                .foregroundStyle(appState.appTheme.themeColor())
                .frame(height: 200)
        }
        
    }
}

#Preview {
    TaoHomeView()
        .environmentObject(TaoAppState())
}
Licensed under CC BY-NC-SA 4.0
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy