Updated for Xcode 12.5
SwiftUI gives us simple hooks into lists to let us move rows around by attaching an onMove(perform:)
modifier to items in a list, and have it call a method of our choosing when a move operation happens. That method needs to accept a source IndexSet
and a destination Int
, like this:
func move(from source: IndexSet, to destination: Int) {
// move the data here
}
When moving several items it’s always a good idea to move the later ones first so that you avoid moving other items and getting your indexes confused. Fortunately, Swift’s sequences have a built-in way to move index sets for us, so we can just pass the parameters along and have it work correctly.
As an example, we could create a ContentView
struct that sets up an array of three username strings, and asks SwiftUI to move them around calling a move()
method. In order to activate moving – i.e., to make the drag handles appear – it also adds an edit button to the navigation view so the user can toggle editing mode.
Here’s the code:
struct ContentView: View {
@State private var users = ["Paul", "Taylor", "Adele"]
var body: some View {
NavigationView {
List {
ForEach(users, id: \.self) { user in
Text(user)
}
.onMove(perform: move)
}
.toolbar {
EditButton()
}
}
}
func move(from source: IndexSet, to destination: Int) {
users.move(fromOffsets: source, toOffset: destination)
}
}
SPONSORED Check out Stream's cross-platform open source chat SDK on GitHub! Write once and deploy your app with fully featured chat UI on iOS and macOS.
Sponsor Hacking with Swift and reach the world's largest Swift community!
Link copied to your pasteboard.