SwiftUI:“@Published”属性更改时未刷新“带有组的动态列表”
Posted
技术标签:
【中文标题】SwiftUI:“@Published”属性更改时未刷新“带有组的动态列表”【英文标题】:SwiftUI: "Dynamic List with groups" not refreshed when an `@Published` property is changed 【发布时间】:2019-11-12 11:20:40 【问题描述】:我正在尝试在 SwiftUI 中创建一个 动态分组列表,我遇到了一个问题,如果我更改标记为内部 ForEach 的 @Published 的集合除非我转到不同的屏幕/工作表,否则该更改在 UI 中不可见。我不明白我所做的是正确还是错误的错误,关于“SwiftUI 中的动态分组列表”主题的资源非常有限,所以我希望你能指出我正确的方向。
这是我的设置:
型号:
class Product: Identifiable, ObservableObject
let id = UUID()
var name: String
init(name: String)
self.name = name
class Category: Identifiable, ObservableObject
let id = UUID()
@Published var items = [Product]()
var categoryName = ""
class Categories: ObservableObject
@Published var items = [Category]()
和视图
struct ProductListView: View
@ObservedObject var categories: Categories = Categories()
var body: some View
List
ForEach(categories.items) category in
Section(header: Text(category.categoryName))
ForEach(category.items) item in
Text(item.name)
.listStyle(GroupedListStyle())
func appendProduct()
let product = Product(name: self.$name.wrappedValue, quantity: 1, complated: false)
let basicCategory = "Generic"
let existingCategory = self.categories.items.filter($0.categoryName == basicCategory).first
if (existingCategory?.items != nil)
// Changes here do not refresh the UI
existingCategory?.items.append(product)
else
let category = Category()
category.categoryName = basicCategory
category.items.append(product)
self.categories.items.append(category)
当我附加到 Category
(existingCategory?.items.append(product)
) 的项目时,UI 不会更新,除非我通过导航或使用 .sheet()
进入不同的视图
有人知道这里有什么问题吗?我对 Swift 和 SwfitUI 很陌生。
【问题讨论】:
我不认为你可以在另一个ObservableObject
中拥有一个 ObservableObject
.. 也许先尝试一下
【参考方案1】:
您的视图只观察categories
,因此只有直接更改categories
才会导致您的视图重绘。
这就是为什么self.categories.items.append(Category())
总是会导致视图重绘,而existingCategory?.items.append(product)
不会。
existingCategory?.items.append(product)
只是将一个元素添加到categories
类别元素之一,但类别元素仍然相同,因此直接对观察到的categories
进行的位置没有更改。
你可以试试这个:
self.$categories.items[0].items.wrappedValue.append(product)
这也将始终导致您的视图重绘,因为您直接在categories
绑定上进行操作。
【讨论】:
谢谢,这就是答案。为了避免使用 0 作为硬编码索引,我做了以下操作: let index = self.categories.items.firstIndex(where: (item) -> Bool in item.categoryName == basicCategory ) ?? 0 self.$categories.items[index].items.wrappedValue.append(product)【参考方案2】:在 Swift 中,Category 和 Product 应该是一个结构体。
这为您提供了价值语义,这是 SwiftUI 用来检测变化的。 IE。对产品的更改被检测为对类别的更改,这被检测为对 SwiftUI 正在观察的@Published
项目的更改。
【讨论】:
以上是关于SwiftUI:“@Published”属性更改时未刷新“带有组的动态列表”的主要内容,如果未能解决你的问题,请参考以下文章
来自 @Published 属性的 SwiftUI 动画从视图外部更改
SwiftUI - 更改 @Published 结构时是不是可以触发 didSet?
SwiftUI @Published 属性正在 DetailView 中更新
当从另一个 ObservedObject 链接到 Published 属性时,视图不会对更改做出反应