TechnologiesSwiftUILists and Collections

ReorderableSingleCollectionIdentifier struct

iOSmacOStvOSwatchOSvisionOS✓ renders

An opaque, empty type used to identify reorderable containers and modifiers

How it works

ReorderableSingleCollectionIdentifier is the value SwiftUI uses to name one specific element inside a collection that supports interactive reordering. When a list lets people drag rows into a new order, the framework needs a stable way to refer to the item being moved apart from its current position, and this identifier serves that role for a single element. Reach for it when you work with the reorder machinery that SwiftUI threads through a List or ForEach — it is the handle that ties a move gesture back to a concrete piece of your data.

  1. Give each element a stable identity

    A reorderable identifier is only meaningful when SwiftUI can tell your elements apart, so the underlying collection must expose stable identities. Here ForEach(fruits, id: \.self) keys each row by the string value itself, which is what lets the framework form a ReorderableSingleCollectionIdentifier for the dragged item rather than tracking it by a row index that shifts during the move.

  2. Enable reordering with onMove

    Attaching .onMove to the ForEach declares the collection reorderable and supplies the closure SwiftUI calls when an element is dragged to a new slot. The identifier conceptually pins down the single element involved in that gesture, while the closure receives the from and to offsets you apply against your backing array.

  3. Commit the move back to your data

    The move closure is where the reordering becomes real. Calling fruits.move(fromOffsets: from, toOffset: to) rewrites the @State array so the element identified for the drag lands at its new index, and the resulting state change drives the animated update of the List.

  4. Expose the reordering affordance

    Reordering needs a way to enter edit mode, which is what the EditButton() in the .toolbar provides. Once the List inside the NavigationStack is editable, drag handles appear and SwiftUI begins tracking the single dragged element so your .onMove handler runs.

Try it — Replace fruits.move(fromOffsets: from, toOffset: to) inside .onMove with an empty body so the array is never updated, then drag a row and watch it snap back to its original position — proof that the identified element's new placement only sticks when you commit the move to your data.

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.

ReorderableSingleCollectionIdentifier.swift
struct ReorderableSingleCollectionIdentifierDemo: View {
    @State private var fruits = ["Apple", "Banana", "Cherry", "Date"]

    var body: some View {
        NavigationStack {
            List {
                ForEach(fruits, id: \.self) { fruit in
                    Text(fruit)
                }
                .onMove { from, to in
                    fruits.move(fromOffsets: from, toOffset: to)
                }
            }
            .navigationTitle("Fruits")
            .toolbar { EditButton() }
        }
    }
}
Live preview
fruit fruit fruit fruit 9:41 Fruits
fruit fruit fruit fruit 9:41 Fruits
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →