How to get Binding via dollar prefix in SwiftUI
Issue #488
The dollar is not a prefix, it seems to be a generated code for property wrapper, and each kind of property wrapper can determine which value it return via this dollar sign
State
and ObservedObject
are popular property wrappers in SwiftUI
State
Read State
A persistent value of a given type, through which a view reads and monitors the value.
If we have a simple State, we can access its 3 forms
1 | @State private var image: UIImage |
and here is what
1 | image // UIImage |
Also, with State, we can access Binding
via projectedValue
1 | _image.projectedValue // Binding<UIImage> |
ObservableObject
Read ObservedObject
For a simple ObservableObject
, we can see its 3 forms
1 | class ViewModel: ObservableObject { |
1 | @ObservedObject var viewModel: ViewModel = ViewModel() |
1 | viewModel // ViewModel |
If we view the source code of ObservableObject
, we can see its Wrapper
which uses dynamicMemberLookup
to provide Binding
1 | @propertyWrapper public struct ObservedObject<ObjectType> : DynamicProperty where ObjectType : ObservableObject { |
Derived State
If we have a struct with @State
in a SwiftUI view, we can access its property as Binding. This derived state mechanism is done via Dynamic keypath member lookup feature of Swift 5.1
1 | struct ViewModel { |
Take a look at the interface of Binding
1 | /// A value and a means to mutate it. |
So if use $viewModel.image
we can access its property as Binding
1 | viewModel.image // UIImage? |
Conclusion
So now we know how to get Binding
from State
and ObservableObject
, and the mysterious dollar sign. These are both convenient but confusing at first, but if we use it more, it will make more sense and hopefully we can learn to do the same for our own property wrappers