How to share published model between two view models in SwiftUI?

谁说胖子不能爱 提交于 2021-01-28 05:05:25

问题


I am trying to access the same shared model within two different view models. Both associated views need to access the model within the view model and need to edit the model. So I can't just use the EnvironmentObject to access the model.

I could pass the model to the view model through the view, but this wouldn't keep both model versions in sync. Is there something that could work like binding? Because with binding I can access the model but then it won't publish the changes in this view.

Simplified Example:

First view in NavigationView with adjacent view two:

struct ContentView1: View {
    @StateObject var contentView1Model = ContentView1Model()
    var body: some View {
        NavigationView {
            VStack{
                TextField("ModelName", text: $contentView1Model.model.name)
                NavigationLink(destination: ContentView2(model: contentView1Model.model)){
                    Text("ToContentView2")
                }
            }
        }
    }
}

class ContentView1Model: ObservableObject {
    @Published var model = Model()
    //Some methods that modify the model
}

Adjacent view 2 which needs access to Model:

struct ContentView2: View {
    @StateObject var contentView2Model: ContentView2Model
    
    init(model: Model) {
        self._contentView2Model = StateObject(wrappedValue: ContentView2Model(model: model))
    }
    
    var body: some View {
        TextField("ModelName", text: $contentView2Model.model.name)
    }
}

class ContentView2Model: ObservableObject {
    
    @Published var model: Model // Tried binding but this won't publish the changes.
    
    init(model: Model) {
        self.model = model
    }
}

Model:

struct Model {
    var name = ""
}

Thanks for the help!


回答1:


Ok, Model is struct, so it is just copied when you pass it from ContentViewModeltoContentView2Model` via

ContentView2(model: contentView1Model.model)

This is the case when it is more preferable to have model as standalone ObservableObject, so it will be passed by reference from one view model into another.

class Model: ObservableObject {
    @Published var name = ""
}

and then you can inject it and modify in any needed subview, like

struct ContentView1: View {
    @StateObject var contentView1Model = ContentView1Model()
    var body: some View {
        NavigationView {
            VStack{
                ModelEditView(model: contentView1Model.model)       // << !!
                NavigationLink(destination: ContentView2(model: contentView1Model.model)){
                    Text("ToContentView2")
                }
            }
        }
    }
}

struct ContentView2: View {
    @StateObject var contentView2Model: ContentView2Model
    
    init(model: Model) {
        self._contentView2Model = StateObject(wrappedValue: ContentView2Model(model: model))
    }
    
    var body: some View {
        ModelEditView(model: contentView2Model.model)       // << !!
    }
}

struct ModelEditView: View {
    @ObservedObject var model: Model
    
    var body: some View {
        TextField("ModelName", text: $model.name)
    }
}


来源:https://stackoverflow.com/questions/65505053/how-to-share-published-model-between-two-view-models-in-swiftui

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!