简体   繁体   中英

How to pass data between ViewModels in SwiftUI

I have this use case where I have a parent view and a child view. Both of the views have their own corresponding ViewModels.

ParentView:

struct ParentView: View {

  @StateObject var parentViewModel = ParentViewModel()

  var body: some View {
    NavigationView {
        List {
            TextField("Add Name", text: $parentViewModel.newListName)
            NavigationLink(destination: ChildView()) {
                Label("Select Products", systemImage: K.ListIcons.productsNr)
            }
        }
    }
}

ParentViewModel:

class AddListPopoverViewModel: ObservableObject {

  @Published var newListName: String = ""

  func saveList() {
    // some logic to save to CoreData, method would be called via a button
    // how do I reference "someString" from ChildViewModel in this ViewModel?
  }
}

ChildView:

struct ChildView: View {

    @StateObject var childViewModel = ChildViewModel()

    var body: some View {
        NavigationView {
            List{
                Text("Some element")
                    .onTapGesture {
                        childViewModel.alterData()
                    }      
            }
        }
    }
}

ChildViewModel:

class ChildViewModel: ObservableObject {
    @Published var someString: String = ""

    func alterData() {
       someString = "Toast"
    }
}

My question now is, how do I pass the new value of "someString" from ChildViewModel into the ParentViewModel, in order to do some further stuff with it? I've tried to create a @StateObject var childViewModel = ChildViewModel() reference in the ParentViewModel, but that does obviously not work, as this will create a new instance of the ChildViewModel and therefore not know of the changes made to "someString"

Most likely you would use a binding for this situation:

struct ChildView: View {
    @Binding var name: String

    var body: some View {
        NavigationView {
            List{
                Text("Some element")
                    .onTapGesture {
                        name = "Altered!"
                    }      
            }
        }
    }
}

And in the parent:

struct ParentView: View {

  @StateObject var parentViewModel = ParentViewModel()

  var body: some View {
    NavigationView {
        List {
            TextField("Add Name", text: $parentViewModel.newListName)
            NavigationLink(destination: ChildView(name: $parentViewModel.newListName)) {
                Label("Select Products", systemImage: K.ListIcons.productsNr)
            }
        }
    }
}

Also, I think you can remove the NavigationView view from ChildView . Having it ParentView is enough.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM