Passing @Published property where @Binding is expected?

Viewed 281

When some calculation happens in viewModel I want to present modal view. Normally I need to set some boolean binding for method:

.fullScreenCover(isPresented: $isGalleryPresented) {
    GalleryPickerView())
}

where isGalleryPresented, is @State definied in view. However browsing SO, i have found out that I could have property in viewModel:

@Published var isGalleryPresented = false

and then do something like this:

.fullScreenCover(isPresented: $viewModel.isGalleryPresented) {
    GalleryPickerView()
}

And this works just fine, although I don't know how. fullScreenCover method argument of type isPresented: Binding<Bool>, and I pass as far as I can tell a publisher. How does this work?

1 Answers

Your viewModel is a wrapped property of @ObservedObject, which provides binding via keypath subscript to wrapped observable object properties.

Here is a corresponding part of declaration:

@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) @propertyWrapper @frozen public 
struct ObservedObject<ObjectType> : DynamicProperty where ObjectType : ObservableObject {

    /// A wrapper of the underlying observable object that can create bindings to
    /// its properties using dynamic member lookup.
    @dynamicMemberLookup @frozen public struct Wrapper {

        /// Returns a binding to the resulting value of a given key path.
        ///
        /// - Parameter keyPath  : A key path to a specific resulting value.
        ///
        /// - Returns: A new binding.
        public subscript<Subject>(dynamicMember keyPath: ReferenceWritableKeyPath<ObjectType, Subject>) -> Binding<Subject> { get }
    }
Related