[英]My view doesn't update after modifying an object of a list inside an ObservableObject
我是 SwiftUI 的新手。 想象一下,我正在为一家商店构建一个应用程序。 我有一个产品详细信息列表的视图,以及两个按钮: Pin (添加到收藏夹)和Delete 。
我的问题是关于Pin按钮(删除按钮工作正常)。 当我单击它时,该图标应该变为填充的 pin 图标,而不是经典的 pin 图标。 当我返回之前的视图时,列出 5 个最新产品和固定产品(在两个不同的部分),这个应该更新并将修改后的产品添加到固定产品列表中。
但是现在,图钉图标根本没有改变(但是当我返回并再次进入产品详细信息视图时会改变)并且之前的视图不会在固定的产品列表中显示产品(而且我不能检查它是否在我重新加载视图时出现,因为我无法返回并再次进入该视图,因为这是主视图)。
我使用了一些标签来表明视图确实修改了商店和产品本身,如下所示。
因此,视图具有产品本身的属性和商店的属性——控制所有产品列表的存储库:
struct DetailsView: View {
@StateObject var store: Store
@State var product: Product
var body: some View {
List {
Section {
VStack(alignment: .leading) {
Text(product.name)
Text(product.brand)
.font(.subheadline)
.foregroundColor(.secondary)
}
.padding(.vertical, 6.0)
} header: {
Text("Product")
}
Section {
Button {
product.pinned = !product.pinned
} label: {
HStack {
if (product.pinned) {
Image(systemName: "pin.fill")
Text("Unpin")
} else {
Image(systemName: "pin")
Text("Pin")
}
}
.padding(.vertical, 6.0)
}
Button {
store.remove(product.id)
} label: {
HStack {
Image(systemName: "trash")
Text("Delete")
}
.foregroundColor(.red)
.padding(.vertical, 6.0)
}
}
}
.navigationTitle(product.name)
.navigationBarTitleDisplayMode(.inline)
}
}
我的商店仅由一个属性定义,即产品列表:
class Store: ObservableObject {
@Published private var products: [Product]
…
}
最后,产品由不同的属性(名称、品牌、固定)定义:
class Product: Identifiable {
static private var count: Int = 0
let id: Int
@Published var name: String
@Published var brand: String
@Published var pinned: Bool = false
…
}
回顾一下,我的问题是:我当前的视图未更新(固定按钮未更改),并且当我返回之前的视图时未更新(该产品未出现在固定的产品列表中)。
有谁知道如何解决这个问题? 非常感谢。
附言
我之前显示固定项目的视图工作正常,除了这个。 我通过使用固定项目初始化我的商店来测试它,它们会出现。
你有2个问题:
1、点击pin图标时,当前页面的pin状态不会改变。
为什么? 因为 Product 类没有继承 ObservableObject 类,所以不能被观察。 要修复它,请继承 ObservableObject 类。
class Product: ObservableObject, Identifiable {
static private var count: Int = 0
let id: Int
@Published var name: String
@Published var brand: String
@Published var pinned: Bool = false
…
}
在您的 DetailsView 中,记得观察产品:
struct DetailsView: View{
@ObeservedObject product: Product
...
}
2、在当前页面点击pin不会改变你之前的页面。
原因是虽然Store类是observabledObject,也就是说发布的属性“products”被别人观察到了,但是数组“products”的对象是“product”,是一个类。
所以实际上数组“products”包含一些指向“product”的指针。 即使像“pined”这样的产品属性发生变化,指针(地址)也不会改变。 所以当有人观察发布的“产品”时,他会说“哦,什么都没发生,不需要刷新视图”。
要修复它,在您之前的视图中,您应该观察产品,而不是商店。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.