Home > front end >  Deleting CoreData from SwiftUI List with Sections
Deleting CoreData from SwiftUI List with Sections

Time:12-18

Goal

I want to delete an item from a SectionedFetchRequest on a ForEach inside a List. The only solutions I have found are for a regular FetchRequest I have managed to delete it from the UIList but not from the CoreData's ViewContext.

My question is unique because I'm trying to delete from a SectionedFetchRequest which is different than a FetchRequest

    @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()
}

CodePudding user response:

This is how you would use the link...

Add this to the TodoRowView(todo: todo)

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

And you need this method in the View

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

Or you can use your current setup that uses onDelete on the ForEach

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

That uses this method

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

And of course for any of this to work you need a working

@Environment(\.managedObjectContext) var viewContext

At the top of your file

  • Related