Manjunath
Manjunath

Reputation: 11

My View is not getting Updated after Editing from Modal View SwiftUI

I have View called TransferFlowView() and I have an ObservedObject. struct TransferFlowView: View { @ObservedObject var transferListVM = TransferListViewModel() }

In TransferListViewModel(), I have a function to Update viewModel. class TransferListViewModel: ObservableObject { init() { fetch } } And I call that update function in Modal View. So Whenever I click submit and dismiss Modal View, The TransferFlowView() is not getting Updated.

I tried using binding property, used .onChange on TransferFlowView. It's not refreshing. I want the view to be loaded, like first time, when it loads.

Upvotes: 0

Views: 99

Answers (1)

Dmitry
Dmitry

Reputation: 2887

ObservableObject relies on a synthesizes publisher objectWillChange to be triggered when there is a change, otherwise a view that observes this object through @ObservedObject wouldn't know when to refresh.

There are two ways to trigger that:

  1. Manually by calling objectWillChange.send()
struct TransferFlowView: View {
    @StateObject var transferListVM = TransferListViewModel()
    
    var body: some View {
        
        VStack {
            Text(transferListVM.update)
            
            Button(action: {
                transferListVM.fetch()
            }) {
                Text("Update")
            }
        }
    }
}

class TransferListViewModel: ObservableObject {
    var update = UUID().uuidString
    
    init() {
        fetch()
    }
    
    func fetch() {
        update = UUID().uuidString
        objectWillChange.send()
    }
}

Here if you comment out objectWillChange you will see that the text doesn't change on the view.

  1. Using @Published property.

If you add @Published to the property, it will automatically trigger objectWillChange when you assign a new value. This code will have the same result:

class TransferListViewModel: ObservableObject {
    @Published var update = UUID().uuidString
    
    init() {
        fetch()
    }
    
    func fetch() {
        update = UUID().uuidString
    }
}

You also need to pay attention where you initilize a new instance of TransferListViewModel. In your current code you use @ObservedObject and it will be initializing a new instance of the view model every time you refresh the view. For that you have to pass the already initialized instance from outside.

Otherwise, you can use @StateObject which will call the initializer only once.

Upvotes: 0

Related Questions