How it works
EditActions is an option set that declares which mutating operations a collection-backed view permits while it's being edited — principally moving and deleting rows. SwiftUI consults these options to decide whether to offer the move grips and delete controls that appear when a List or ForEach enters edit mode, so you rarely construct an EditActions value by hand. Instead you opt in to each capability by attaching the corresponding action handler, and reach for the type when you want to reason about, or constrain, the set of edits a dynamic collection should support.
Enable row removal with onDelete
Supplying an
onDeletehandler signals that the collection supports the delete action, which is what causes SwiftUI to surface the swipe-to-delete and red minus controls. The closure receives anIndexSetof the affected positions, which you forward straight to the model — herefruits.remove(atOffsets: offsets).Enable reordering with onMove
Attaching an
onMovehandler adds the move action to the set, drawing the drag grips on each row in edit mode. The closure hands you a sourceIndexSetand a destination index, applied to the array withfruits.move(fromOffsets: src, toOffset: dst).Bind the actions to a dynamic ForEach
Edit actions belong on a
ForEachdriven by mutable data, since SwiftUI needs identity to map offsets back to elements. TheForEach(fruits, id: \.self)here over the@Statearrayfruitsis what the move and delete handlers reorder and remove from.Toggle edit mode with EditButton
The enabled actions only become visible once the surrounding view enters edit mode. Placing an
EditButton()in the.toolbarflips the environment's edit mode on and off, revealing the move grips and delete affordances thatonDeleteandonMoveopted into.
.onMove { src, dst in ... } modifier and tap Edit — the drag-to-reorder grips disappear while the delete controls remain, showing that each handler contributes its own action to the set independently.Example & preview
Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.
struct EditActionsDemo: View {
@State private var fruits = ["Apple", "Banana", "Cherry", "Date"]
var body: some View {
NavigationStack {
List {
ForEach(fruits, id: \.self) { fruit in
Text(fruit)
}
.onDelete { offsets in
fruits.remove(atOffsets: offsets)
}
.onMove { src, dst in
fruits.move(fromOffsets: src, toOffset: dst)
}
}
.navigationTitle("Fruits")
.toolbar { EditButton() }
}
}
}