1
votes

I'm trying to updating view with SwiftUI and binding. I have a MainView that observes changes in ViewModel. I would like this view to respond to changes in viewModel.data.image. I don't know how to pass a value to HeaderView.

Currently this code refuses to compile. I get an error:

Value of type 'ObservedObject <LockedCourseViewModel> .Wrapper' has no dynamic member 'course' using key path from root type

View:

struct MainView: View {
    @ObservedObject var viewModel = ViewModel()
    
    var body: some View {
        VStack {
            HeaderView(image: $viewModel.data.image)
        }
    }
}

ViewModel:

class ViewModel: ObservableObject {    
    @Published var data: Model?
    
    func fetchData(id: Int) {
        // fetching some data from api
        self.data = Model(data: data)
    }
}

Model:

class Model: ObservableObject {
    @Published var image: URL
}

HeaderView:

struct HeaderView: View {
    @Binding var image: URL?
}

Thank you for help!

1

1 Answers

0
votes

As your Model is also a class, you don't need Binding, pass instead reference to entire model and use image from it.

var body: some View {
    VStack {
        // once data is fetched HeaderView will be updated
        HeaderView(model: viewModel.data ?? Model())
    }
}

and

struct HeaderView: View {
    @ObservedObject var model: Model

    // ... other code
}

Update: alternate with binding to image

var body: some View {
    let boundImage = Binding(
        get: { viewModel.data?.image },
        set: { viewModel.data?.image = $0 }
    )
    return VStack {
        HeaderView(image: boundImage)
    }
}