I'm unsure why my view isn't getting updated when I have a view model nested inside another. My understanding was that a @Published property in the child view model would trigger a change in the parent viewModel, causing that to push changes to the UI.
This is the child view model:
class FilterViewModel : ObservableObject, Identifiable {
var id = UUID().uuidString
var name = ""
var backgroundColour = ""
@Published var selected = false
private var cancellables = Set<AnyCancellable>()
init(name: String){
self.name = name
$selected.map { _ in
self.selected ? "Orange" : "LightGray"
}
.assign(to: \.backgroundColour, on: self)
.store(in: &cancellables)
}
func changeSelected() {
self.selected = !self.selected
}
}
The following works as expected, on clicking the button the background colour is changed.
struct ContentView: View {
@ObservedObject var filterVM = FilterViewModel(name: "A")
Button(action: { filterVM.changeSelected()}, label: {
Text(filterVM.name)
.background(Color(filterVM.backgroundColour))
})
}
However, I want to have an array of filter view models so tried:
class FilterListViewModel: ObservableObject {
@Published var filtersVMS = [FilterViewModel]()
init(){
filtersVMS = [
FilterViewModel(name: "A"),
FilterViewModel(name: "B"),
FilterViewModel(name: "C"),
FilterViewModel(name: "D")
]
}
}
However, the following view is not updated when clicking the button
struct ContentView: View {
@ObservedObject var filterListVM = FilterListViewModel()
Button(action: { filterListVM[0].changeSelected()}, label: {
Text(filterListVM[0].name)
.background(Color(filterListVM[0].backgroundColour))
})
}
Alternate solution is to use separated view for your sub-model:
struct FilterView: View {
@ObservedObject var filterVM: FilterViewModel
var body: some View {
Button(action: { filterVM.changeSelected()}, label: {
Text(filterVM.name)
.background(Color(filterVM.backgroundColour))
})
}
}
so in parent view now we can just use it as
struct ContentView: View {
@ObservedObject var filterListVM = FilterListViewModel()
// ...
FilterView(filterVM: filterListVM[0])
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With