Search code examples
swiftuiswiftui-list

Delete Core Data Row When Long Pressing


I have created a new Mac OS xcode application with core data and was playing around with the default code that generates that allows you to add items.

But I wanted to change the way in which the rows are deleted. With using a long press gesture to trigger the delete.

View:

var body: some View {
    List {
        ForEach(items) { item in
            Text("Item at \(item.timestamp!, formatter: itemFormatter)")
                
        }
        //.onDelete(perform: deleteItems) Want to change this command to the one below
          .onLongPressGesture(minimumDuration: 1.5, perform: deleteItems)

    }
    .toolbar {
        Button(action: addItem) {
            Label("Add Item", systemImage: "plus")
        }
    }
}

Delete Item Function

private func deleteItems(offsets: IndexSet) {
    withAnimation {
        offsets.map { items[$0] }.forEach(viewContext.delete)

        do {
            try viewContext.save()
        } catch {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            let nsError = error as NSError
            fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
        }
    }

But I get the following error

Cannot convert value of type '(IndexSet) -> ()' to expected argument type '() -> Void'


Solution

  • ".onDelete(perform action: ((IndexSet) -> Void)?)" and ".onLongPressGesture(minimumDuration: Double = 1.5, perform action: @escaping () -> Void)" as you can see have different signatures. So what you are doing is not working.

    You could try something like this:

    List {
        ForEach(items, id: \.self) { item in
            Text("Item at \(item)")
                .onLongPressGesture(minimumDuration: 1.5, perform: {deleteItems2(item)})
        }
       // .onDelete(perform: deleteItems)
    }
        
    private func deleteItems2(_ item: Item) {
        if let ndx = items.firstIndex(of: item) {
            viewContext.delete(items[ndx])
        do {
            try viewContext.save()
        } catch {
            // Replace this implementation with code to handle the error appropriately.
            // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
            let nsError = error as NSError
            fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
        }
      }
    }