Fix app background colors not updating when preference changed
This only fully fixes it on iOS 17, but it seems to be the best we can do
This commit is contained in:
parent
ee5f9a62ff
commit
f5e9f66f76
|
@ -74,4 +74,9 @@ extension PreferenceStore {
|
||||||
public func hasFeatureFlag(_ flag: FeatureFlag) -> Bool {
|
public func hasFeatureFlag(_ flag: FeatureFlag) -> Bool {
|
||||||
enabledFeatureFlags.contains(flag)
|
enabledFeatureFlags.contains(flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public func getValue<Key: PreferenceKey>(preferenceKeyPath: KeyPath<PreferenceStore, PreferencePublisher<Key>>) -> Key.Value {
|
||||||
|
self[keyPath: preferenceKeyPath].preference.wrappedValue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,26 +8,11 @@
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import Combine
|
import Combine
|
||||||
|
import TuskerPreferences
|
||||||
|
|
||||||
extension View {
|
extension View {
|
||||||
@MainActor
|
func appGroupedListBackground(container: UIAppearanceContainer.Type) -> some View {
|
||||||
@ViewBuilder
|
self.modifier(AppGroupedListBackground(container: container))
|
||||||
func appGroupedListBackground(container: UIAppearanceContainer.Type, applyBackground: Bool = true) -> some View {
|
|
||||||
if #available(iOS 16.0, *) {
|
|
||||||
if applyBackground {
|
|
||||||
self
|
|
||||||
.scrollContentBackground(.hidden)
|
|
||||||
.background(Color.appGroupedBackground.edgesIgnoringSafeArea(.all))
|
|
||||||
} else {
|
|
||||||
self
|
|
||||||
.scrollContentBackground(.hidden)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self
|
|
||||||
.onAppear {
|
|
||||||
UITableView.appearance(whenContainedInInstancesOf: [container]).backgroundColor = .appGroupedBackground
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func appGroupedListRowBackground() -> some View {
|
func appGroupedListRowBackground() -> some View {
|
||||||
|
@ -35,11 +20,45 @@ extension View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct AppGroupedListRowBackground: ViewModifier {
|
private struct AppGroupedListBackground: ViewModifier {
|
||||||
|
let container: any UIAppearanceContainer.Type
|
||||||
@Environment(\.colorScheme) private var colorScheme
|
@Environment(\.colorScheme) private var colorScheme
|
||||||
|
@Environment(\.pureBlackDarkMode) private var environmentPureBlackDarkMode
|
||||||
|
|
||||||
|
private var pureBlackDarkMode: Bool {
|
||||||
|
// using @PreferenceObserving just does not work for this, so try the environment key when available
|
||||||
|
// if it's not available, the color won't update automatically, but it will be correct when the view is created
|
||||||
|
if #available(iOS 17.0, *) {
|
||||||
|
environmentPureBlackDarkMode
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func body(content: Content) -> some View {
|
func body(content: Content) -> some View {
|
||||||
if colorScheme == .dark, !Preferences.shared.pureBlackDarkMode {
|
if #available(iOS 16.0, *) {
|
||||||
|
if colorScheme == .dark, !pureBlackDarkMode {
|
||||||
|
content
|
||||||
|
.scrollContentBackground(.hidden)
|
||||||
|
.background(Color.appGroupedBackground.edgesIgnoringSafeArea(.all))
|
||||||
|
} else {
|
||||||
|
content
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
content
|
||||||
|
.onAppear {
|
||||||
|
UITableView.appearance(whenContainedInInstancesOf: [container]).backgroundColor = .appGroupedBackground
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct AppGroupedListRowBackground: ViewModifier {
|
||||||
|
@Environment(\.colorScheme) private var colorScheme
|
||||||
|
@PreferenceObserving(\.$pureBlackDarkMode) private var pureBlackDarkMode
|
||||||
|
|
||||||
|
func body(content: Content) -> some View {
|
||||||
|
if colorScheme == .dark, !pureBlackDarkMode {
|
||||||
content
|
content
|
||||||
.listRowBackground(Color.appGroupedCellBackground)
|
.listRowBackground(Color.appGroupedCellBackground)
|
||||||
} else {
|
} else {
|
||||||
|
@ -47,3 +66,31 @@ private struct AppGroupedListRowBackground: ViewModifier {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@propertyWrapper
|
||||||
|
private struct PreferenceObserving<Key: TuskerPreferences.PreferenceKey>: DynamicProperty {
|
||||||
|
typealias PrefKeyPath = KeyPath<PreferenceStore, PreferencePublisher<Key>>
|
||||||
|
|
||||||
|
let keyPath: PrefKeyPath
|
||||||
|
@StateObject private var observer: Observer
|
||||||
|
|
||||||
|
init(_ keyPath: PrefKeyPath) {
|
||||||
|
self.keyPath = keyPath
|
||||||
|
self._observer = StateObject(wrappedValue: Observer(keyPath: keyPath))
|
||||||
|
}
|
||||||
|
|
||||||
|
var wrappedValue: Key.Value {
|
||||||
|
Preferences.shared.getValue(preferenceKeyPath: keyPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
private class Observer: ObservableObject {
|
||||||
|
private var cancellable: AnyCancellable?
|
||||||
|
|
||||||
|
init(keyPath: PrefKeyPath) {
|
||||||
|
cancellable = Preferences.shared[keyPath: keyPath].sink { [unowned self] _ in
|
||||||
|
self.objectWillChange.send()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -143,3 +143,33 @@ extension UIMutableTraits {
|
||||||
set { self[PureBlackDarkModeTrait.self] = newValue }
|
set { self[PureBlackDarkModeTrait.self] = newValue }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@available(iOS 17.0, *)
|
||||||
|
private struct PureBlackDarkModeKey: UITraitBridgedEnvironmentKey {
|
||||||
|
static let defaultValue: Bool = false
|
||||||
|
|
||||||
|
static func read(from traitCollection: UITraitCollection) -> Bool {
|
||||||
|
traitCollection[PureBlackDarkModeTrait.self]
|
||||||
|
}
|
||||||
|
|
||||||
|
static func write(to mutableTraits: inout any UIMutableTraits, value: Bool) {
|
||||||
|
mutableTraits[PureBlackDarkModeTrait.self] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension EnvironmentValues {
|
||||||
|
var pureBlackDarkMode: Bool {
|
||||||
|
get {
|
||||||
|
if #available(iOS 17.0, *) {
|
||||||
|
self[PureBlackDarkModeKey.self]
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
if #available(iOS 17.0, *) {
|
||||||
|
self[PureBlackDarkModeKey.self] = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -157,7 +157,7 @@ struct ReportView: View {
|
||||||
.appGroupedListRowBackground()
|
.appGroupedListRowBackground()
|
||||||
}
|
}
|
||||||
.listStyle(.insetGrouped)
|
.listStyle(.insetGrouped)
|
||||||
.appGroupedListBackground(container: UIHostingController<ReportView>.self, applyBackground: true)
|
.appGroupedListBackground(container: UIHostingController<ReportView>.self)
|
||||||
.alertWithData("Error Reporting", data: $error, actions: { error in
|
.alertWithData("Error Reporting", data: $error, actions: { error in
|
||||||
Button("OK") {}
|
Button("OK") {}
|
||||||
}, message: { error in
|
}, message: { error in
|
||||||
|
|
Loading…
Reference in New Issue