How to delete in CoreData in an MacOS SwiftUI application (.onDelete is not working)

If you use the sample code for a swiftUi App for MacOS the .onDelete function profided is not working, because .onDelete is only working in IOS. How can I use the .deleteItems function for MacOS?

import SwiftUI

import CoreData



struct ContentView: View {

    @Environment(\.managedObjectContext) private var viewContext



    @FetchRequest(

        sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)],

        animation: .default)

    private var items: FetchedResults<Item>



    var body: some View {

        List {

            ForEach(items) { item in

                Text("Item at \(item.timestamp!, formatter: itemFormatter)")

            }

            .onDelete(perform: deleteItems)

        }

        .toolbar {

            Button(action: addItem) {

                Label("Add Item", systemImage: "plus")

            }

        }

    }



    private func addItem() {

        withAnimation {

            let newItem = Item(context: viewContext)

            newItem.timestamp = Date()



            do {

                try viewContext.save()

            } catch {

                let nsError = error as NSError

                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")

            }

        }

    }



    private func deleteItems(offsets: IndexSet) {

        withAnimation {

            offsets.map { items[$0] }.forEach(viewContext.delete)



            do {

                try viewContext.save()

            } catch {

                let nsError = error as NSError

                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")

            }

        }

    }

}
Answered by workingdogintokyo in 676631022

The ".onDelete(...)" works on MacOS, iOS and MacCatalyst. Here is a very basic example, using MacOS 11.4, xcode 12.5, target ios 14.5, macCatalyst 11.3 and MacOS 11.4. You have to swipe your mouse right to left.

import SwiftUI

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    @State var items = ["1","2","3"]

    private func deleteItems(offsets: IndexSet) {
        withAnimation {
            print("deleteItems")
        }
    }

    private func addItem() {
        withAnimation {
            print("addItem")
        }
    }

    var body: some View {
        List {
            ForEach(items, id: \.self) { item in
                Text("Item at \(item)")
            }.onDelete(perform: deleteItems)
        }
        .toolbar {
            Button(action: addItem) {
                Label("Add Item", systemImage: "plus")
            }
        }
    }
}
Accepted Answer

The ".onDelete(...)" works on MacOS, iOS and MacCatalyst. Here is a very basic example, using MacOS 11.4, xcode 12.5, target ios 14.5, macCatalyst 11.3 and MacOS 11.4. You have to swipe your mouse right to left.

import SwiftUI

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    @State var items = ["1","2","3"]

    private func deleteItems(offsets: IndexSet) {
        withAnimation {
            print("deleteItems")
        }
    }

    private func addItem() {
        withAnimation {
            print("addItem")
        }
    }

    var body: some View {
        List {
            ForEach(items, id: \.self) { item in
                Text("Item at \(item)")
            }.onDelete(perform: deleteItems)
        }
        .toolbar {
            Button(action: addItem) {
                Label("Add Item", systemImage: "plus")
            }
        }
    }
}

.onDelete is working fine on the mac when swiping from right to left with magic mouse or trackpad.

But i prefer to use a context menu and add the delete function there.

var body: some View {
        List {
            ForEach(items) { item in
                Text("Item at \(item.timestamp!, formatter: itemFormatter)")
                    .contextMenu(ContextMenu(menuItems: {
                        Button(action: {
                            viewContext.delete(item)

                            do {
                                try viewContext.save()
                            } catch {
                                let nsError = error as NSError
                                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
                            }
                        }, label: {
                            Text("Delete")
                        })
                    }))
            }
            .onDelete(perform: deleteItems)
        }
        .toolbar {
            #if os(iOS)
            EditButton()
            #endif

            Button(action: addItem) {
                Label("Add Item", systemImage: "plus")
            }
        }
    }
How to delete in CoreData in an MacOS SwiftUI application (.onDelete is not working)
 
 
Q