在我的视图模型中,我有这个属性和方法:
@Published var cats: [Cat] = [] //this gets populated later
当我更新其中一只猫时:
func updateCatQuantity(_ cat:Cat, qty: Int) {
if let index = cats(of: cat) {
cats[index].quantity = qty
}
}
视图不会刷新。
didSet
上的 cats
不会被调用。我认为这与 Cat
是一个类而不是一个结构有关。其定义如下:
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"]
}
}
当猫的数量改变时如何让视图刷新?
有2个问题
@Published
仅在“值”改变时触发刷新。更改 class
中的变量不被视为“值”更改。切换到
struct
是“简单”的改变。
struct Cat: Identifiable, Hashable {
var id = UUID()
var title: String = ""
var quantity: Int = 0
}
但是问题#2 是一个更大的问题。通过覆盖
Hashable
,您将告诉 SwiftUI 仅在 View
更改时触发 id
重新加载。
要在 iOS 13-16 中观察
class
,该对象必须符合 ObservableObject
并用 @StateObject
、@ObservedObject
或 @EnvironmentObject
包裹,在您想要看到变化的每个级别进行相应的操作。
class Cat: Identifiable, Hashable, ObservableObject {
var id = UUID()
@Published var title: String = ""
@Published var quantity: Int = 0
func hash(into hasher: inout Hasher) {
hasher.combine(id)
hasher.combine(title)
hasher.combine(quantity)
}
static func == (lhs: Cat, rhs: Cat) -> Bool {
return lhs.id == rhs.id
&& lhs.title == rhs.title
&& lhs.quantity == rhs.quantity
}
}
在 iOS 17+ 中,您可以适当地使用
@Observable
代替 ObservableObject
以及 @State
和 @Bindable
。
@Observable
class Cat: Identifiable{
var id = UUID()
var title: String = ""
var quantity: Int = 0
func hash(into hasher: inout Hasher) {
hasher.combine(id)
hasher.combine(title)
hasher.combine(quantity)
}
static func == (lhs: Cat, rhs: Cat) -> Bool {
return lhs.id == rhs.id
&& lhs.title == rhs.title
&& lhs.quantity == rhs.quantity
}
}