Currently i am using subview without using viewmodel and which is woking fine..UI is updating on value change. (find code below) but i want to create viewmodel for subview and update UI on value change..
Normal code without viewmodel
struct MainView: View {
@State private var selectedTag: String?
var body: some View {
VStack {
ForEach(products, id: .description) { item in
SubView(productTag: item.productId, selectedTag: self.$selectedTag)
}
}
}
}
struct SubView: View {
var productTag: String?
@Binding var selectedTag: String?
var body: some View {
Button(action: {
self.selectedTag = self.productTag
})
}
}
with viewmodel (but not working for me – UI is not updating)
struct MainView: View {
@State private var selectedTag: String?
var body: some View {
VStack {
ForEach(products, id: .description) { item in
SubView(viewModel: SubViewViewModel(productTag: item.productId ?? "", selectedTag: self.selectedTag ?? ""))
}
}
}
}
struct SubView: View {
private var viewModel: SubViewViewModel
var body: some View {
Button(action: {
viewModel.selectedTag = viewModel.productTag
})
}
}
class SubViewViewModel: ObservableObject {
var productTag: String
@Published var selectedTag: String?
init(productTag: String, selectedTag: String) {
self.productTag = productTag
self.selectedTag = selectedTag
}
}
I might missing some concept, kindly suggest the solution for same.
4
Answers
If you want
SubView
to alterMainView
via a shared model you will first need to initialize it as a@StateObject
on theMainView
, becauseMainView
is the owner.Then you pass that same viewModel to
SubView
as an@ObservedObject
sinceSubView
is only borrowing it.Make your view model a singleton.
You can pass the view model as an environment object to your subview like this or use a Binding variable as well.
Since you are using @State, which only works with simple data types. For the view to be updated as per your view model, you need to use @StateObject as viewmodel is a complex data type.
Please check this link: https://levelup.gitconnected.com/state-vs-stateobject-vs-observedobject-vs-environmentobject-in-swiftui-81e2913d63f9
You shouldn’t create
ViewModel
onSubView
to update value fromMainView
, but rather pass downViewModel
fromMainView
toSubView
If your
SubView
has some business that doesn’t want to botherMainView
, and you only needselectedTag
fromMainView
, you should keep using@Binding
and create a@StateObject private var viewModel
insideSubView