【问题标题】:Deleting CoreData from SwiftUI List with Sections从带有部分的 SwiftUI 列表中删除 CoreData
【发布时间】:2022-01-20 18:05:29
【问题描述】:

目标

我想从列表中ForEach 上的SectionedFetchRequest 中删除一个项目。我找到的唯一解决方案是针对常规的FetchRequest,我已设法将其从 UIList 中删除,但没有从 CoreData 的 ViewContext 中删除。

我的问题很独特,因为我试图从不同于 FetchRequest 的 SectionedFetchRequest 中删除

    @SectionedFetchRequest(entity: Todo.entity(), sectionIdentifier: \.dueDateRelative, sortDescriptors: [NSSortDescriptor(keyPath: \Todo.dueDate, ascending: true)], predicate: nil, animation: Animation.linear)
    var sections: SectionedFetchResults<String, Todo>
    var body: some View {
        NavigationView {
            List {      
                ForEach(sections) { section in
                    Section(header: Text(section.id.description)) {
                        ForEach(section) { todo in
                            TodoRowView(todo: todo)
                                .frame(maxWidth: .infinity)
                                .listRowSeparator(.hidden)
                        }
                        .onDelete { row in
                            deleteTodo(section: section.id.description, row: row)
                            }
                        }

                    }
                }
    func deleteTodo(section: String, row: IndexSet) {
        // Need to delete from list and CoreData viewContex.
    }
// My old way of deleting notes with a regular fetch Request
func deleteNote(at offsets: IndexSet) {
    for index in offsets {
        let todo = todos[index]
        viewContext.delete(todo)
    }
    try? viewContext.save()
}

【问题讨论】:

  • 这能回答你的问题吗? Delete data from CoreData
  • @loremipsum 嗯,我不确定在我的上下文中如何利用该答案,因为我正在使用 ForEach 循环。我还没有看到 sectionedFetchRequest 的删除解决方案。
  • 该答案是您可以通过该方法使用swipeActions 的最实用的答案。您仍然可以按原样使用 indexSet,但您必须为该部分中的数组执行此操作。它不适用于所有对象。
  • @loremipsum 尝试了该解决方案,但我会在我的上下文中为 .onDelete 放置什么?我不知道将什么传递给该函数或访问待办事项。

标签: ios swift iphone core-data swiftui


【解决方案1】:

这就是您使用链接的方式...

将此添加到TodoRowView(todo: todo)

.swipeActions(content: {
    Button(role: .destructive, action: {
        deleteTodo(todo: todo)
    }, label: {
        Image(systemName: "trash")
    })
})

而你需要这个方法在View

public func deleteTodo(todo: Todo){
    viewContext.delete(todo)
    do{
        try viewContext.save()
    } catch{
        print(error)
    }
}

或者您可以在ForEach 上使用使用onDelete 的当前设置

.onDelete { indexSet in
    deleteTodo(section: Array(section), offsets: indexSet)
    }

使用这种方法

func deleteTodo(section: [Todo], offsets: IndexSet) {
    for index in offsets {
        let todo = section[index]
        viewContext.delete(todo)
    }
    try? viewContext.save()
}

当然,要让其中任何一个工作,你需要一个工作

@Environment(\.managedObjectContext) var viewContext

在文件的顶部

【讨论】:

  • 成功了!再次感谢。整个数组和 IndexSet 部分仍然令人困惑,我想我需要弄清楚更多。
  • @JustinComstock onDelete 提供用户选择删除的索引项集 (indexSet)。滑动时只有一个,但如果您在List 上放置一个编辑按钮,您可以删除多个项目(这就是您需要循环的原因)。每个section 都有自己的ForEach/todo 数组项,需要通过数组删除它,因为您必须搜索特定部分。
猜你喜欢
  • 2020-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-19
  • 2021-09-06
  • 2023-03-30
  • 2021-02-07
  • 2022-07-28
相关资源
最近更新 更多