Moving List Items Using Drag and Drop in SwiftUI Mac Apps
Mac apps usually use drag and drop to rearrange items in a list. You search for how to move list items in SwiftUI, and you find a bunch of examples for iOS that use the .onMove
modifier. But when you start to type .onMove
in your Mac list, Xcode’s autocomplete shows only an .onMoveCommand
modifier. If you try to use .onMove
directly on a list in a Mac app, you’ll get a compiler error.
SwiftUI has an .onMoveCommand
modifier to move items in a list in a SwiftUI Mac app, but it works with the keyboard, not with drag and drop. How do you use drag and drop to move items in a SwiftUI list in a Mac app?
.onMove Requires ForEach on Mac
The .onMove
modifier is the modifier to use to move list items using drag and drop in SwiftUI Mac apps. But you must place a ForEach
statement inside the list to enable .onMove
. The ForEach
statement takes two arguments: the array of items you’re showing in the list and an ID that uniquely identifies each list item.
Apply the .onMove
modifier to the ForEach
block. The .onMove
modifier’s closure takes two arguments: the indices for the list items being moved and the drop destination. Call the array’s move
method to reorder the list items.
The following code creates a list of a book’s chapters that you can rearrange using drag and drop:
// The chapter has an id property that uniquely identifies it.
List {
ForEach($book.chapters, id: \.id) { $chapter in
TextField("", text: $chapter.title)
}
.onMove { indices, destination in
book.chapters.move(fromOffsets: indices,
toOffset: destination)
}
}