ios – Updating StateObject from the View and expecting changes back to the view


I have a ListView with a list of users; tapping on each item takes me to the Detail page.

ListView

NavigationStack {
    List {
        ForEach(viewModel.users) { user in
            NavigationLink(value: user) {
                Text(user.givenName)
            }
        }
    }
    .navigationTitle("UserList")
    .navigationDestination(for: User.self, destination: { user in
        FormView(user) // this gets called twice, annoying but no solution yet. 
    })

FormView

@StateObject private var viewModel = ViewModel()

var body: some View {
    VStack {
        
        HStack {
            TextField("First", text: Binding(
                    get: { viewModel.user.first ?? "" },
                    set: { viewModel.user.first = $0 }))
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .font(.system(size: 16))
                .autocapitalization(.none)
                          
            TextField("Middle", text: Binding(
                    get: { viewModel.user.last ?? "" },
                    set: { viewModel.user.last = $0 }))
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .font(.system(size: 16))
                .autocapitalization(.none)

             ...
        }
    }
    .onAppear {
        viewModel.setUser(user) // deferred set, to ensure ObservableObject is created
        // viewModel.user = user // perhaps its not good to set directly
    }
    ...

var user: User
      
init(_ user: User) {
    self.user = user // received the user from the list page
    // viewModel.user = user // forbidden by XCode, doesn't compile
}

The user comes from the List page, and I assign it to a local variable first and wait for the view to appear before I set it on the viewModel.

on the ViewModel side, upon breakpoint, I do see that the user was passed and set, only the View is not updating.

ViewModel

class ViewModel: ObservableObject {
     
    @Published var user: User = User(id: 0)

    func setUser(_ user: User) {
        self.user = user // user 
        objectWillChange.send() // forcing update - no use
    }

Question

  1. Main Question is if a change was pushed from View to the ObservableObject and a reaction was expected back in the View, how to do in context of my question.

  2. This gets called twice on the tap from the list page, another dilemma.

 .navigationDestination(for: User.self, destination: { user in
     FormView(user) // this gets called twice, annoying but no solution yet. 
 })

Edit – This worked, really?

.onAppear {
    // viewModel.setUser(user)
    // viewModel.user = user
    DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
        viewModel.user = user
    }
}

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img