Swift核心数据从属性列表中删除项目

问题描述

我正在研究一个核心数据项目。 目前,我有一个具有以下属性的实体(项目):

@NSManaged public var title: String?
@NSManaged public var list: [String]

我正在使用带有ForEach的列表在列表中显示实体。通过导航链接,如果用户选择一个项目,我将打开另一个视图。

主列表代码

struct ItemList: View {
@Environment(\.managedobjectContext) var viewContext
@FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \Item.title,ascending: true)]) 
var ItemFetch: FetchedResults<Item>

   var body: some View {
      NavigationView {
         List {
            ForEach(ItemFetch,id: \.self {item in
               NavigationLink(destination: ItemView(Item: item) {
                  Text(item.title)
               }
            }
            .onDelete(perform: removeItem(at:))
         }
      }
   }
   private func removeItem(at offsets: IndexSet) {
           for index in offsets {
               let item = ItemFetch[index]
               viewContext.delete(item)
        }
    }
}

第二个查看代码

struct ItemView: View {

@Environment(\.managedobjectContext) var viewContext
@Observedobject var Item: Item

var body: some View{
NavigationView {
   List {
      ForEach { Item.list.indices { entry in
         Text(self.Item.list[entry]
      }
   }
   .navigationBarItem(
          trailing:
               Button(action: {
                   self.Item.list.append("SubItem")
       }) {
                   Text("Add SubItem")
        })
      }
   }
}

用户可以通过按按钮将SubItem添加到列表中。

也可以通过滑动删除项目列表中的项目。

现在,我希望用户也可以通过滑动来删除“子项目”列表中的“子项目”。 如果我尝试实现相同的功能,则用户将通过删除不是我想要的SubItem来删除Item。

我不知道如何使用FetchRequest仅获取名为list的属性。有没有办法做到这一点,或者有其他方法可以删除子项?

谢谢。

解决方法

问题中发布的代码实际上无效。

如果您希望能够在子项上运行查询,则可能要为其创建一个新实体,并使用Core Data 1-to-n关系链接这两个实体。

但是,如果您要坚持使用字符串数组来存储子项,则可以通过添加以下内容来实现滑动删除功能:

.onDelete(perform: removeSubItem(at:))

转到ItemView中的ForEach,即

ForEach(Item.list,id: \.self) { entry in // you should actually call it "item" to avoid confusion...
    Text(entry)
}.onDelete(perform: removeSubItem(at:))

removeSubItem可能看起来像这样:

private func removeSubItem(at offsets: IndexSet) {
    for index in offsets {
        Item.list.remove(at: index)  // you should actually call it "item" to avoid confusion...
        try? viewContext.save()
    }
}