Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

274
Views
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"


Solution: As proposed by Josh, I went with the approach to use a single ViewModel instead of two. To achieve this, the ParentView needs a .environmentObject(T) modifier.

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)
            }
        }
    }.environmentObject(parentViewModel)
}

The ChildView then references that environment Object via @EnvironmentObject without an initializer:

struct ChildView: View {

    @EnvironmentObject var parentViewModel: ParentViewModel

    var body: some View {
        NavigationView {
            List{
                Text("Some element")
                    .onTapGesture {
                        parentViewModel.alterData()
                    }      
            }
        }
    }
}
over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

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.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!