Updated for Xcode 12.0
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) {
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)
}
.navigationBarItems(trailing: EditButton())
}
}
func move(from source: IndexSet, to destination: Int) {
users.move(fromOffsets: source, toOffset: destination)
}
}
SPONSORED Would you describe yourself as knowledgeable, but struggling when you have to come up with your own code? Fernando Olivares has a new book containing iOS rules you can immediately apply to your coding habits to see dramatic improvements, while also teaching applied programming fundamentals seen in refactored code from published apps.
Sponsor Hacking with Swift and reach the world's largest Swift community!
Link copied to your pasteboard.