Swift 根据类别使用ForEach获取多个DisclosureGroup

Swift 根据类别使用ForEach获取多个DisclosureGroup

问题描述

我现在正在构建一个视图,我尝试根据类别使用ForEach获取多个DisclosureGroup。这是容易的部分。我的问题在于第二个数组,我想要获取具有指定类别的项目。

代码如下:

    @Environment(\.modelContext) var context
    @Query private var category: [CategoryModel]
    @Query private var bonsai: [BonsaiModel]

    @State private var searchQuery = ""

    var body: some View {
        NavigationStack {
            VStack {

            }
            VStack(alignment: .center) {
                List {
                    Section {
                        // Query category to build DisclosureGroup
                        ForEach(category) { categories in // Loop through category
                            DisclosureGroup(categories.name) {

                                ForEach(bonsai) { items in // Loop through bonsai, where bonsai.category = category
                                    Text(items.name)
                                        .bold()
                                    if let category = items.category {
                                        Text(category.name) // show category.title
                                            .foregroundColor(Color(.systemGray))
                                            .bold()

                                    } else {
                                        Text(" ")
                                            .padding(.top, 4)
                                    }


                                }

                            }
                        }


                    }
                }
                .padding(.horizontal, 8)
                .padding(.top, 8)
                .listStyle(.inset)

我在其中放了两个文本项,以查看我尝试在“bonsai” ForEach中获取的数据。

这里有一张图片,来展示我试图实现的目标:

Swift 根据类别使用ForEach获取多个DisclosureGroup

现在你可以看到全部内容,但是你可以将类别用作“过滤器”,只在它们的组内显示。

我猜它可能会用到compactMap或filter,但我不知道如何让它起作用。

这里是模型:

@Model
final class BonsaiModel {
    var uuid: UUID
    var timestamp: Date
    var purchased: Date
    var price: Double
    var name: String
    var isFavorite: Bool
    var age: String

    @Attribute(.externalStorage)
    var bonsaiImageData: Data?

    @Relationship(deleteRule: .nullify, inverse: \CategoryModel.bonsai)
    var category: CategoryModel?
    @Relationship(deleteRule: .nullify, inverse: \SpeciesModel.bonsai)
    var species: SpeciesModel?

    init(price: Double = 0.00,
         name: String = "",
         isFavorite: Bool = false,
         age: String = "",
         bonsaiImageData: Data? = nil
    ) {
        self.uuid = UUID()
        self.timestamp = Date()
        self.purchased = Date()
        self.price = price
        self.name = name
        self.isFavorite = isFavorite
        self.age = age
        self.bonsaiImageData = bonsaiImageData

    }


}

@Model
final class CategoryModel {
    @Attribute(.unique) var name: String = ""

    var bonsai: [BonsaiModel]?

    init(name: String) {
        self.name = name

    }

}

@Model
final class SpeciesModel {
    @Attribute(.unique) var name: String = ""

    var bonsai: [BonsaiModel]?

    init(name: String) {
        self.name = name
    }

}

解决方案

鉴于您的数据模型,您可以直接访问CategoryModel中的BonsaiModel的关联属性,这样您只会获得属于当前CategoryModel的对象,而无需执行任何过滤或匹配对象的操作。

ForEach(category) { categories in
    DisclosureGroup(categories.name) {
        ForEach(categories.bonsai ?? []) { items in
            Text(items.name)
            //...
        }
    }
}

旁注:我建议将关系的多方面设为非可选项

var bonsai: [BonsaiModel] = []

同时,通过这种解决方案您还可以从视图中删除对BonsaiModel的查询

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程