问题
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 ContentView
Modelto
ContentView2Model` 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