0
votes

How to update view, when view models publish var's (user's) , name property is updated. I do know why its happening but what is the best way to update the view in this case.

class User {
    var id  = "123"
    @Published  var name = "jhon"
}

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

struct ContentView: View {
     @ObservedObject var viewModel = ViewModel() 
    
    var body: some View  {
        userNameView 
    }

    var userNameView: some View  {
        Text(viewModel.user.name)
            .background(Color.red)
            .onTapGesture {
                viewModel.user.name += "update"
                print( viewModel.user.name)
            }
    }
}

so one way i do it, is by using onReceive like this,

var body: some View  {

         userNameView
             .onReceive(viewModel.user.$name){ output in

                    let tmp = viewModel.user
                           viewModel.user = tmp
                    print("onTapGesture",output)

          }
}

but it is not a good approach it will update all view using users properties. should i make a @state var for the name? or should i just make a ObservedObject for user as well?

3
Does this answer your question? @Published property not triggering anything - lorem ipsum

3 Answers

1
votes

Make you class conform to ObservableObject

class User: ObservableObject {
    var id  = "123"
    @Published  var name = "jhon"
}

But he catch with that is that you have to observe it directly you can't chain it in a ViewModel

Use @ObservedObject var user: User in a View

0
votes

Use struct instead of class.

struct User {
    var id  = "123"
    var name = "jhon"
}
0
votes

You should use struct:


import SwiftUI

struct User {
    var id: String
    var name: String
}

class ViewModel : ObservableObject {
    @Published var user : User = User(id: "123", name: "Mike")
}

struct ContentView: View {
    
    @ObservedObject var viewModel: ViewModel = ViewModel()
    
    var body: some View  {
        userNameView
    }

    var userNameView: some View  {
        
        Text(viewModel.user.name)
            .background(Color.red)
            .onTapGesture {
                viewModel.user.name += " update"
                print( viewModel.user.name)
            }
    }
}