In my view model I have this property and method:
@Published var cats: [Cat] = [] //this gets populated later
When I update one of the cats as such:
func updateCatQuantity(_ cat:Cat, qty: Int) {
if let index = cats(of: cat) {
cats[index].quantity = qty
}
}
The view does not get refreshed. didSet on cats does not get called. I think it has something to do with the fact that Cat is a class instead of a struct. Here's how it's defined:
class Cat: BaseMapperModel, Identifiable, Hashable {
static func == (lhs: Cat, rhs: Cat) -> Bool {
return ObjectIdentifier(lhs) == ObjectIdentifier(rhs)
}
var id = UUID()
var title: String = ""
var quantity: Int = 0
func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
override func mapping(map: Map) {
title <- map["title"]
quantity <- map["qty"]
}
}
How can I get the view to refresh when the quantity of a cat is changed?
There are 2 issues
@Publishedonly triggers a refresh when the "value" changes. Changing a variable in aclassis not considered a "value" change.Switching to a
structis the "easy" change.But issue #2 is a bigger deal. By overriding
Hashableyou are telling SwiftUI to only triggerViewreloads when theidchanges.To observe a
classin iOS 13-16 the object has to conform toObservableObjectand be wrapped with@StateObject,@ObservedObjector@EnvironmentObject, appropriately at every level you want to see changes.in iOS 17+ you can use
@Observableinstead of anObservableObjectwith@Stateand@Bindableappropriately.