Updated for Xcode 14.0 beta 1
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)
}
}
Download this as an Xcode project
SPONSORED In-app subscriptions are a pain. The code can be hard to write, hard to test, and full of edge cases. RevenueCat makes it straightforward and reliable so you can get back to building your app.
Sponsor Hacking with Swift and reach the world's largest Swift community!
Link copied to your pasteboard.