3

Can anyone tell me how to disable the Delete swipe action for a list of items inside a NavigationView, while retaining the ability to delete list items when the NavigationView is in edit mode.

I have tried conditionally passing a closure or nil to the onDelete modifier, based on the editMode environment variable, but this doesn't seem to work for me. I also tried to use deleteDisabled, but Swift seems to ignore the change in my state variable, when passed to those modifiers.

Below is some sample code to reproduce the problem I have:

@State private var list = [1,2,3,4,5]
@State private var editMode = EditMode.inactive
    
var body: some View {
   NavigationView {
      List {
         ForEach(list, id: \.self) { item in
            Text("\(item) \(String(self.editMode.isEditing))")
         }
         .onDelete(perform: self.editMode.isEditing ? { index in list.remove(atOffsets: index) } : nil)
         .deleteDisabled(!self.editMode.isEditing) // <-- Always disables delete, even in edit mode
      }
      .navigationBarItems(leading: EditButton(), trailing: Text(editMode == .active ? "Editing" : "Not Editing"))
      .environment(\.editMode, $editMode)
  }
}

Interestingly, the items in the list and the trailing Text in the navigation bar update just like they are supposed to whenever the editMode changes, but the change in editMode seems to be completely ignored by the onDelete and deleteDisabled modifiers, which appear to be in the same scope.

I am using Xcode 14.0 Beta.

jdelano
  • 206
  • 1
  • 8
  • 1
    Your code works. the delete swipe gesture is diabled when not editiong. It is enabled when editing. Tested in Xcode 13.4.1 (13F100) – mahan Jun 16 '22 at 13:53
  • 1
    This can be helpful https://stackoverflow.com/a/72631027/12299030. – Asperi Jun 16 '22 at 13:54
  • 3
    Thank you @mahan, I just confirmed that it does work in my Xcode 13.4.1 install, but it still does not work in Xcode 14.0 Beta, so I'm guessing it is a bug in the new Xcode version. At least I'm not going crazy after all... :-) – jdelano Jun 16 '22 at 14:02
  • Also, thank you, @Asperi... your link gave me some other ideas that I will check out. – jdelano Jun 16 '22 at 14:07
  • Btw, `onDelete { index in list.remove(atOffsets: index) }` is enough. – mahan Jun 16 '22 at 14:14
  • Thanks @mahan, yeah, my code tended to get "busier" the more I was trying to debug why this wasn't working. I'm going to revert back to your suggestion and clean things up. I'll also submit a bug report to Apple... Thanks again for your help. – jdelano Jun 16 '22 at 14:21
  • Did you ever find a solution? I have basically the same code, and same issue. – Tomer Shemesh Aug 13 '23 at 14:48
  • Weird part is it works in reverse for me. I can enable swipe to delete when not in edit mode, and block it when in edit mode, but as soon as I swap the boolean logic it stops working. – Tomer Shemesh Aug 13 '23 at 14:50

0 Answers0