Initial description
I currently have a dynamic list and I'm using the SwiftUI built-in editMode
feature and the built-in EditButton()
in order to let the user to delete items from the list.
For the deletion part, I am using the onDelete
modifier which adds the trailing red Delete swipe gesture as you now.
This is an example:
List {
ForEach(someList) { someElement in
Text(someElement.name)
}
.onDelete { (indexSet) in }
.onMove { (source, destination) in }
}
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
EditButton()
}
}
.environment(\.editMode, $editMode)
The goal
Now I also want to use the iOS 15 .swipeActions
modifier that allows adding our own custom leading or trailing swipe gestures.
I want the user to be also able to edit the list element by swiping right, so I added a leading swipe action to my row:
Text(someElement.name)
.swipeActions(edge: .leading) {
Button("Edit") { }
}
The button action would obviously contain a code allowing the edition.
The issue
Using the .swipeActions
modifier breaks the normal behavior of the editMode
and particularly the .onDelete
modifier. Indeed, with this setup I cannot swipe left anymore in order to delete the row.
So here's the question: how can I use the SwiftUI editMode
's .onDelete
modifier on a list alongside with my own custom leading
swipe action ?
Minimal reproducible example
Xcode playgrounds, for iOS 15.
import SwiftUI
import PlaygroundSupport
struct SomeList: Identifiable {
let id: UUID = UUID()
var name: String
}
let someList: [SomeList] = [
SomeList(name: "row1"),
SomeList(name: "row2"),
SomeList(name: "row3")
]
struct ContentView: View {
@State private var editMode = EditMode.inactive
var body: some View {
NavigationView {
List {
ForEach(someList) { someElement in
Text(someElement.name)
.swipeActions(edge: .leading) {
Button("Edit") { }
}
}
.onDelete { (indexSet) in }
.onMove { (source, destination) in }
}
.toolbar {
ToolbarItem(placement: .navigationBarLeading) {
EditButton()
}
}
.environment(\.editMode, $editMode)
}
}
}
PlaygroundPage.current.setLiveView(ContentView())
You can test the following: if you comment or remove this part:
.swipeActions(edge: .leading) {
Button("Edit") { }
}
Then the .onDelete
modifier works again. Putting it back on breaks the .onDelete
feature.
Additional information
I am building this app for iOS 15 since I'm using the .swipeActions
modifier.
I am willing to accept any solution that would allow achieving my goal, which is letting the user to swipe left to delete the row and swipe right to trigger any edition code. Even if that means using another way that the .swipeActions
modifier, or another way that the .onDelete
modifier of SwiftUI editMode
, or both.
I had to build the app for iOS 15 only because of this .swipeActions
modifier, so if I can build the app for lower iOS versions it is even better.
Let me now if you need any additional information. Thank you.