Skip to content

Commit 3ad11e6

Browse files
committed
added .environment modifiers to modify a predefined EnvironmentValue or set a value for an EnvironmentKey
1 parent b1b4ca1 commit 3ad11e6

File tree

4 files changed

+52
-3
lines changed

4 files changed

+52
-3
lines changed

Examples/Sources/GreetingGeneratorExample/GreetingGeneratorApp.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ struct GreetingGeneratorApp: App {
2929

3030
Toggle("Selectable Greeting", active: $isGreetingSelectable)
3131
if let latest = greetings.last {
32-
Text(latest)
32+
EnvironmentDisplay()
33+
.environment(key: TestKey.self, value: latest)
3334
.padding(.top, 5)
3435
.textSelectionEnabled(isGreetingSelectable)
3536

@@ -51,3 +52,15 @@ struct GreetingGeneratorApp: App {
5152
}
5253
}
5354
}
55+
56+
struct EnvironmentDisplay: View {
57+
@Environment(TestKey.self) var value: String?
58+
var body: some View {
59+
Text(value ?? "nil")
60+
}
61+
}
62+
63+
struct TestKey: EnvironmentKey {
64+
typealias Value = String?
65+
static let defaultValue: Value = nil
66+
}

Sources/SwiftCrossUI/Environment/Environment.swift

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,19 @@
3636
/// ```
3737
@propertyWrapper
3838
public struct Environment<Value>: DynamicProperty {
39-
var keyPath: KeyPath<EnvironmentValues, Value>
39+
var keyPath: KeyPath<EnvironmentValues, Value>?
40+
var environmentKey: EnvironmentKey.Type?
4041
var value: Box<Value?>
4142

4243
public func update(
4344
with environment: EnvironmentValues,
4445
previousValue: Self?
4546
) {
46-
value.value = environment[keyPath: keyPath]
47+
if let keyPath {
48+
value.value = environment[keyPath: keyPath]
49+
} else if let environmentKey {
50+
value.value = environment[environmentKey] as! Value
51+
}
4752
}
4853

4954
public var wrappedValue: Value {
@@ -63,4 +68,9 @@ public struct Environment<Value>: DynamicProperty {
6368
self.keyPath = keyPath
6469
value = Box(value: nil)
6570
}
71+
72+
public init<Key: EnvironmentKey>(_ type: Key.Type) where Value == Key.Value {
73+
self.environmentKey = type
74+
self.value = Box(value: nil)
75+
}
6676
}

Sources/SwiftCrossUI/Environment/EnvironmentValues.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,14 @@ public struct EnvironmentValues {
221221
environment[keyPath: keyPath] = newValue
222222
return environment
223223
}
224+
225+
/// Returns a copy of the environment with the specified key set to the
226+
/// provided new value.
227+
public func with<T: EnvironmentKey>(key: T.Type, value: T.Value) -> Self {
228+
var environment = self
229+
environment[key] = value
230+
return environment
231+
}
224232
}
225233

226234
/// A key that can be used to extend the environment with new properties.

Sources/SwiftCrossUI/Views/Modifiers/EnvironmentModifier.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,21 @@ package struct EnvironmentModifier<Child: View>: View {
3737
)
3838
}
3939
}
40+
41+
extension View {
42+
/// Modifies the environment of the View its applied to.
43+
public func environment<T: EnvironmentKey>(key: T.Type, value: T.Value) -> some View {
44+
EnvironmentModifier(self) { environment in
45+
environment.with(key: key, value: value)
46+
}
47+
}
48+
49+
/// Modifies the environment of the View its applied to
50+
public func environment<T>(_ keyPath: WritableKeyPath<EnvironmentValues, T>, _ newValue: T)
51+
-> some View
52+
{
53+
EnvironmentModifier(self) { environment in
54+
environment.with(keyPath, newValue)
55+
}
56+
}
57+
}

0 commit comments

Comments
 (0)