1

I am having property with @StateObject, I am trying to observe change in viewmodel, I am able to print correct result but can not able to show on screen as view is not refreshing.

Tried using binding but not worked because of @StateObject

import SwiftUI
struct AbcView: View {

    @StateObject var abcViewModel: AbcViewModel

    init(abcViewModel: AbcViewModel) {
        self._abcViewModel = StateObject(wrappedValue: abcViewModel)
    }

    var body: some View {
        VStack(alignment: .leading) {
            ZStack(alignment: .top) {
                ScrollView {
                    Text("some txt")
                }
                .overlay(
                    VStack {
                        TopView(content: classViews(data: $abcViewModel.somedata, abcViewModel: abcViewModel))
                        Spacer()
                    }
                )
            }
        }
    }
}

func classViews(data: Binding<[SomeData]>, abcViewModel: AbcViewModel) -> [AnyView] {
    var views: [AnyView] = []

    for element in data {
        views.append(
            VStack(spacing: 0) {
                HStack {
                    print("\(abcViewModel.title(Id: Int(element.dataId.wrappedValue ?? "")) )") // printing correct value
                    Text(abcViewModel.title(Id: Int(element.dataId.wrappedValue ?? ""))) // want to observe change here
                }
            }
                .convertToAnyView())
    }
    return views
}
New iOS Dev
  • 1,937
  • 7
  • 33
  • 67
  • Does this answer your question? [Why is an ObservedObject array not updated in my SwiftUI application?](https://stackoverflow.com/questions/57459727/why-is-an-observedobject-array-not-updated-in-my-swiftui-application) – vicegax May 02 '22 at 09:40
  • @New iOS Dev, did my answer provide solution to your problem? – Mr.SwiftOak May 03 '22 at 09:18

1 Answers1

2

If you are injecting your AbcViewModel into AbcView you should use @ObserverdObject instead of @StateObject , full explanation here Also you should conform tour AbcViewModel to ObservableObject and make your desired property @Published if you want to trigger the change in View . Here is simplified code example:

  1. Making AbcViewModel observable:

    class AbcViewModel: ObservableObject {
     @Published var dataID: String = "" //by changing the @Published   proprty you trigger change in View using it
    }
    
  2. store AbcViewModel as @ObserverdObject:

    struct AbcView: View {
     @ObservedObject var abcViewModel: AbcViewModel
    
     init(abcViewModel: AbcViewModel) {
         self.abcViewModel = abcViewModel
     }
    
     var body: some View {
        //...
     }
    }
    
  3. If you now use your AbcViewModel dataID property anywhere in the project, and you change its value, the property will publish the change and your View (struct) will be rebuilded. Use the same pattern for creating TopView and assigning AbcViewModel to it the same way.

Mr.SwiftOak
  • 1,469
  • 3
  • 8
  • 19