Skip to content

Commit 056f402

Browse files
committed
Add @bindable for two-way bindings into observable models
1 parent 41683d1 commit 056f402

1 file changed

Lines changed: 39 additions & 0 deletions

File tree

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
//
2+
// Bindable.swift
3+
// AndroidSwiftUICore
4+
//
5+
// `@Bindable` wraps a reference to an `@Observable` model and projects a
6+
// two-way `Binding` into any of its properties via `$model.property`. Because
7+
// it wraps an existing reference (from `@State`, `@Environment`, or an init
8+
// parameter), it needs no state storage of its own — writes go straight
9+
// through the reference, and the model's observation drives re-evaluation.
10+
//
11+
12+
@propertyWrapper
13+
@dynamicMemberLookup
14+
public struct Bindable<Value: AnyObject> {
15+
16+
public var wrappedValue: Value
17+
18+
public init(wrappedValue: Value) {
19+
self.wrappedValue = wrappedValue
20+
}
21+
22+
public init(_ wrappedValue: Value) {
23+
self.wrappedValue = wrappedValue
24+
}
25+
26+
public var projectedValue: Bindable<Value> { self }
27+
28+
/// Projects a binding to a property of the wrapped reference. A reference
29+
/// keypath means the set writes through the object without reassigning it.
30+
public subscript<Subject>(
31+
dynamicMember keyPath: ReferenceWritableKeyPath<Value, Subject>
32+
) -> Binding<Subject> {
33+
let object = wrappedValue
34+
return Binding<Subject>(
35+
get: { object[keyPath: keyPath] },
36+
set: { object[keyPath: keyPath] = $0 }
37+
)
38+
}
39+
}

0 commit comments

Comments
 (0)