From c304b3eefe8716f678508b89c9a7d4c91440a7ed Mon Sep 17 00:00:00 2001 From: David Walter Date: Sun, 8 Jan 2023 19:49:49 +0100 Subject: [PATCH] Design system improvements (#45) * Improve DesignSystem Apply Theme to all connected windows * Only use UIKit when available --- IceCubesApp/App/IceCubesApp.swift | 16 +---- .../Sources/DesignSystem/ThemeApplier.swift | 68 +++++++++++++++++++ 2 files changed, 71 insertions(+), 13 deletions(-) create mode 100644 Packages/DesignSystem/Sources/DesignSystem/ThemeApplier.swift diff --git a/IceCubesApp/App/IceCubesApp.swift b/IceCubesApp/App/IceCubesApp.swift index 1182aa03..5a2c7f51 100644 --- a/IceCubesApp/App/IceCubesApp.swift +++ b/IceCubesApp/App/IceCubesApp.swift @@ -33,14 +33,12 @@ struct IceCubesApp: App { var body: some Scene { WindowGroup { appView - .tint(theme.tintColor) + .applyTheme(theme) .onAppear { setNewClientsInEnv(client: appAccountsManager.currentClient) - setBarsColor(color: theme.primaryBackgroundColor) setupRevenueCat() refreshPushSubs() } - .preferredColorScheme(theme.selectedScheme == ColorScheme.dark ? .dark : .light) .environmentObject(appAccountsManager) .environmentObject(appAccountsManager.currentClient) .environmentObject(quickLook) @@ -52,18 +50,15 @@ struct IceCubesApp: App { .environmentObject(PushNotificationsService.shared) .quickLookPreview($quickLook.url, in: quickLook.urls) } - .onChange(of: scenePhase, perform: { scenePhase in + .onChange(of: scenePhase) { scenePhase in handleScenePhase(scenePhase: scenePhase) - }) + } .onChange(of: appAccountsManager.currentClient) { newClient in setNewClientsInEnv(client: newClient) if newClient.isAuth { watcher.watch(streams: [.user, .direct]) } } - .onChange(of: theme.primaryBackgroundColor) { newValue in - setBarsColor(color: newValue) - } } @ViewBuilder @@ -143,11 +138,6 @@ struct IceCubesApp: App { } } - private func setBarsColor(color: Color) { - UINavigationBar.appearance().isTranslucent = true - UINavigationBar.appearance().barTintColor = UIColor(color) - } - private func setupRevenueCat() { Purchases.logLevel = .error Purchases.configure(withAPIKey: "appl_JXmiRckOzXXTsHKitQiicXCvMQi") diff --git a/Packages/DesignSystem/Sources/DesignSystem/ThemeApplier.swift b/Packages/DesignSystem/Sources/DesignSystem/ThemeApplier.swift new file mode 100644 index 00000000..d698bb00 --- /dev/null +++ b/Packages/DesignSystem/Sources/DesignSystem/ThemeApplier.swift @@ -0,0 +1,68 @@ +import SwiftUI +#if canImport(UIKit) +import UIKit +#endif + +public extension View { + func applyTheme(_ theme: Theme) -> some View { + modifier(ThemeApplier(theme: theme)) + } +} + +struct ThemeApplier: ViewModifier { + @ObservedObject var theme: Theme + + func body(content: Content) -> some View { + content + .tint(theme.tintColor) + .preferredColorScheme(theme.selectedScheme == ColorScheme.dark ? .dark : .light) + #if canImport(UIKit) + .onAppear { + setWindowTint(theme.tintColor) + setWindowUserInterfaceStyle(theme.selectedScheme) + setBarsColor(theme.primaryBackgroundColor) + } + .onChange(of: theme.tintColor) { newValue in + setWindowTint(newValue) + } + .onChange(of: theme.selectedScheme) { newValue in + setWindowUserInterfaceStyle(newValue) + } + .onChange(of: theme.primaryBackgroundColor) { newValue in + setBarsColor(newValue) + } + #endif + } + + #if canImport(UIKit) + private func setWindowUserInterfaceStyle(_ colorScheme: ColorScheme) { + allWindows() + .forEach { + switch colorScheme { + case .dark: + $0.overrideUserInterfaceStyle = .dark + case .light: + $0.overrideUserInterfaceStyle = .light + } + } + } + + private func setWindowTint(_ color: Color) { + allWindows() + .forEach { + $0.tintColor = UIColor(color) + } + } + + private func setBarsColor(_ color: Color) { + UINavigationBar.appearance().isTranslucent = true + UINavigationBar.appearance().barTintColor = UIColor(color) + } + + private func allWindows() -> [UIWindow] { + UIApplication.shared.connectedScenes + .compactMap { $0 as? UIWindowScene } + .flatMap { $0.windows } + } + #endif +}