从 coredata SwiftUI 中删除多行

Posted

技术标签:

【中文标题】从 coredata SwiftUI 中删除多行【英文标题】:Delete multiple rows from coredata SwiftUI 【发布时间】:2021-01-13 13:43:40 【问题描述】:

我正在尝试使用编辑模式下的选择同时删除多个核心数据。但是,该行没有被删除。我不确定是什么问题。

我尝试在 ForEach(notes) 上添加 id:\.idid:\.self

我的代码有什么问题?有没有其他方法可以删除多行?

struct TempNoteView: View 
    @Environment(\.managedObjectContext) private var viewContext

    @FetchRequest(sortDescriptors: [],animation: .default)
    private var notes: FetchedResults<Note>
    
    @State var editMode: EditMode = .inactive
    @State var selection = Set<UUID>()

    var body: some View 
        List(selection: $selection) 
            ForEach(notes)  note in
                    NavigationLink(destination: NoteView(note: note)) 
                        Text(note.name ?? "Untitled")
                        Spacer()

                        Button(action: 
                            if note.pin == false 
                                note.pin = true
                                saveContext()
                             else 
                                note.pin = false
                                saveContext()
                            
                        ) 
                            if note.pin 
                                Image("pinned").resizable().frame(width: 23, height: 23, alignment: .center)
                                .padding(.trailing, 10)
                             else 
                                Image("not-pinned").resizable().frame(width: 23, height: 23, alignment: .center)
                                .padding(.trailing, 10)
                            
                        .buttonStyle(PlainButtonStyle())
                        
                    
                    .padding()
                    .listRowInsets(EdgeInsets())
//                    .listRowBackground(Color.gray.opacity(0.1))
                    .background(Color.yellow.opacity(0.3))
                    .clipShape(RoundedRectangle(cornerRadius: 10))
                    .listStyle(SidebarListStyle())
                    .padding(.init(top: 10, leading: 0, bottom: 10, trailing: 0))
                    
                .onDelete(perform: deleteNotes)
            
            .environment(\.editMode, self.$editMode)
            .navigationTitle("Notes")
            .navigationBarItems(
                leading:
                    HStack 
                        editButton
                        deleteButton
                    ,
                trailing: Button(action: addNote(), label: 
                Text("Add Note")
                Image("plus")
            )).onAppear()
                UITableViewCell.appearance().selectionStyle = .none
            
            
    
    private var editButton: some View 
        if editMode == .inactive 
            return Button(action: 
                self.editMode = .active
                self.selection = Set<UUID>()
            ) 
                Text("Edit")
            
        
        else 
            return Button(action: 
                self.editMode = .inactive
                self.selection = Set<UUID>()
            ) 
                Text("Done")
            
        
    
    
    private var deleteButton: some View 
        if editMode == .inactive 
            return Button(action: ) 
                Image("")
            
         else 
            return Button(action: deleteAllNotes) 
                Image(systemName: "trash")
            
        
    
    
    private func deleteAllNotes() 
        for id in selection 
            if let index = notes.lastIndex(where: $0.id == id ) 
                viewContext.delete(notes[index])
            
        
        selection = Set<UUID>()
    
    
    
    func saveContext() 
        do 
            try viewContext.save()
         catch 
            let error = error as NSError
            fatalError("Unresolved Error: \(error)")
        
    
    
    private func deleteNotes(offsets: IndexSet) 
        withAnimation 
            offsets.map  notes[$0] .forEach(viewContext.delete)
            saveContext()
        
    
    
    private func addNote() 
        withAnimation 
            let newNote = Note(context: viewContext)
            newNote.id = UUID()
            newNote.name = "New Note"
            newNote.createdAt = Date()
            newNote.pin = false
            saveContext()
            
        
    

【问题讨论】:

【参考方案1】:

将您的 ForEach 更改为

ForEach(notes, id:\.self)  note in

然后将 Set 更改为将 Notes 作为类型

@State var selection = Set<Notes>()

然后在您的 deleteAllNotes(我将其重命名为 deleteAllSelectedNotes)中删除每个选定的笔记。

private func deleteAllNotes() 
    for item in selection 
        viewContext.delete(item)
    
    selection = Set<Note>()

【讨论】:

以上是关于从 coredata SwiftUI 中删除多行的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI CoreData 过滤列表删除意外失败

无法在 SwiftUI 中使用 ForEach 和 CoreData 将数据正确传递给模态演示

在 SwiftUI 中更新 CoreData 时更新状态变量

如果从 Core Data SwiftUI 中删除,则删除本地通知

浅谈CoreData海量数据(实时动态添加和删除)在SwiftUI列表中分页显示的原理及实现

在 CoreData 记录中进行更改,SwiftUI