diff --git a/Examples/Sources/GreetingGeneratorExample/GreetingGeneratorApp.swift b/Examples/Sources/GreetingGeneratorExample/GreetingGeneratorApp.swift index fa4b984eff..4434769400 100644 --- a/Examples/Sources/GreetingGeneratorExample/GreetingGeneratorApp.swift +++ b/Examples/Sources/GreetingGeneratorExample/GreetingGeneratorApp.swift @@ -29,7 +29,8 @@ struct GreetingGeneratorApp: App { Toggle("Selectable Greeting", active: $isGreetingSelectable) if let latest = greetings.last { - Text(latest) + LatestGreetingDisplay() + .environment(\.latestGreeting, latest) .padding(.top, 5) .textSelectionEnabled(isGreetingSelectable) @@ -51,3 +52,24 @@ struct GreetingGeneratorApp: App { } } } + +/// This intermediate view exists to show the usage of custom environment keys. In reality it is not necessary. +struct LatestGreetingDisplay: View { + @Environment(\.latestGreeting) var value: String? + + var body: some View { + Text(value ?? "nil") + } +} + +struct LatestGreetingKey: EnvironmentKey { + typealias Value = String? + static let defaultValue: Value = nil +} + +extension EnvironmentValues { + var latestGreeting: String? { + get { self[LatestGreetingKey.self] } + set { self[LatestGreetingKey.self] = newValue } + } +} diff --git a/Sources/SwiftCrossUI/Environment/Environment.swift b/Sources/SwiftCrossUI/Environment/Environment.swift index 482dfb25f0..a7a42669d0 100644 --- a/Sources/SwiftCrossUI/Environment/Environment.swift +++ b/Sources/SwiftCrossUI/Environment/Environment.swift @@ -50,7 +50,7 @@ public struct Environment: DynamicProperty { guard let value = value.value else { fatalError( """ - Environment value \(keyPath) used before initialization. Don't \ + Environment value at \(keyPath) used before initialization. Don't \ use @Environment properties before SwiftCrossUI requests the \ view's body. """ diff --git a/Sources/SwiftCrossUI/Environment/EnvironmentValues.swift b/Sources/SwiftCrossUI/Environment/EnvironmentValues.swift index 99ab536d93..082ede2354 100644 --- a/Sources/SwiftCrossUI/Environment/EnvironmentValues.swift +++ b/Sources/SwiftCrossUI/Environment/EnvironmentValues.swift @@ -225,7 +225,7 @@ public struct EnvironmentValues { } /// A key that can be used to extend the environment with new properties. -public protocol EnvironmentKey { +public protocol EnvironmentKey { /// The type of value the key can hold. associatedtype Value /// The default value for the key. diff --git a/Sources/SwiftCrossUI/Views/Modifiers/EnvironmentModifier.swift b/Sources/SwiftCrossUI/Views/Modifiers/EnvironmentModifier.swift index 801354c213..2470da3fb0 100644 --- a/Sources/SwiftCrossUI/Views/Modifiers/EnvironmentModifier.swift +++ b/Sources/SwiftCrossUI/Views/Modifiers/EnvironmentModifier.swift @@ -37,3 +37,14 @@ package struct EnvironmentModifier: View { ) } } + +extension View { + /// Modifies the environment of the View its applied to + public func environment(_ keyPath: WritableKeyPath, _ newValue: T) + -> some View + { + EnvironmentModifier(self) { environment in + environment.with(keyPath, newValue) + } + } +}