在SwiftUI的列表中按类别对核心数据项进行分组

8iwquhpp  于 2023-09-30  发布在  Swift
关注(0)|答案(1)|浏览(70)

我有一个Core Data容器,其中包含两个实体,一个Category和一个Item。可以为物料分配一个类别,也可以将该类别分配给多个物料。
我需要做的是在SwiftUI中按类别将项目分组。
下面的代码没有按类别对所有项目进行分组,它只按类别显示一个项目。如何将具有相同类别的所有物料分组到同一类别组下?

核心数据实体

Category
    Attributes
        name
    Relationship
        items (Type: To Many)

Item
    Attributes
        name
    Relationship
        category (Type: To One)

Swiftui

struct ItemsView: View {
    let selectedList:List

    @EnvironmentObject private var itemSM: ItemServiceModel
    
    var body: some View {
        List{
            ForEach(itemSM.items){ item in
                Section(header: Text(item.category?.name ?? "")) {
                    Text("\(item.name ?? "")")
                }
            }
        }
        .onAppear{
           itemSM.loadItems(forList: selectedList)
       }
    }
}

服务项服务模型

class ItemServiceModel: ObservableObject{
    let manager: CoreDataManager
    @Published var items: [Item] = []

    func loadItems(forList list: List){
        let request = NSFetchRequest<Item>(entityName: "Item")
        
        let sort = NSSortDescriptor(keyPath: \Item.name, ascending: true)
        request.sortDescriptors = [sort]
        
        let filter = NSPredicate(format: "list == %@", list)
        request.predicate = filter

        do{
            items =  try manager.context.fetch(request)
        }catch let error{
            print("Error fetching items. \(error.localizedDescription)")
        }
    }
}

这就是我所看到的:正如您所看到的,GrapesOranges应该在同一个组Fruits & Vegetables中。

编辑1

添加了loadItems()方法和图像。

编辑2

Section中添加一个额外的ForEach,我能够对项目进行分组,现在的问题是它为数组中的项目总数添加了一个部分。

List {
    ForEach(itemSM.items) { item in
        Section(header: Text(item.category?.name ?? "")) {
            ForEach(itemSM.items.filter { $0.category == item.category }) { filteredItem in
                Text("\(filteredItem.name ?? "")")
            }
        }
    }
}

这就是我所看到的,正如您所看到的,应该只存在一个Fruits & Vegetables节。

fhg3lkii

fhg3lkii1#

这就是我的工作。它基本上返回并显示指定列表中的所有类别及其各自的项目。

CategoryServiceModel

func loadCategories(for list: List) -> ([Category], [Item]) {
    let request = NSFetchRequest<Category>(entityName: "Category")

    let predicate = NSPredicate(format: "ANY items IN %@", list.items ?? [])
    request.predicate = predicate

    let sort = NSSortDescriptor(keyPath: \Category.name, ascending: true)
    request.sortDescriptors = [sort]

    do {
        let categories = try manager.context.fetch(request)
        var categories: [Category] = []
        var items: [Item] = []

        for category in categories {
            categories.append(category)
            if let items = category.items?.allObjects as? [Item] {
                let filteredItems = items.filter { $0.list == list }
                items.append(contentsOf: filteredItems)
            }
        }

        return (categories, items)
    } catch let error {
        print("Error fetching categories. \(error.localizedDescription)")
        return ([], [])
    }
}

SwiftUI

List {
      ForEach(categorySM.categories) { category in
          Section(header:Text(category.name ?? "")){
              ForEach(category.items?.allObjects as? [Item] ?? []) { item in
                  Text("\(item.name ?? "")")
              }
          }
      }
  }
  .onAppear{
      categorySM.loadCategories(for: selectedList)
  }

相关问题