【问题标题】:SwiftUI: "Dynamic List with groups" not refreshed when an `@Published` property is changedSwiftUI:“@Published”属性更改时未刷新“带有组的动态列表”
【发布时间】: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.. 也许先尝试一下

标签: ios swift list swiftui


【解决方案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 项目的更改。

【讨论】:

    猜你喜欢
    • 2022-01-04
    • 2020-11-12
    • 2020-10-21
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 2021-09-07
    • 1970-01-01
    • 2021-12-27
    相关资源
    最近更新 更多