Reputation: 2057
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
}
Upvotes: 1
Views: 1967
Reputation: 1834
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:
Making AbcViewModel
observable:
class AbcViewModel: ObservableObject {
@Published var dataID: String = "" //by changing the @Published proprty you trigger change in View using it
}
store AbcViewModel
as @ObserverdObject
:
struct AbcView: View {
@ObservedObject var abcViewModel: AbcViewModel
init(abcViewModel: AbcViewModel) {
self.abcViewModel = abcViewModel
}
var body: some View {
//...
}
}
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.
Upvotes: 3