Moving the rows in a List view
In this recipe, we'll create an app that implements a List
view that allows users to move and reorganize rows.
Getting ready
Create a new SwiftUI project named MovingListRows
.
How to do it…
To make the List
view rows movable, we'll add a modifier to the List
view's ForEach
struct, and then we'll embed the List
view in a navigation view that displays a title and an edit button. The steps are as follows:
- Add a
@State
variable to theContentView
struct that holds an array of countries:@State var countries = ["USA", "Canada", "England", "Cameroon", "South Africa", "Mexico" , "Japan", "South Korea"]
- Replace the body variable's text view with a
NavigationView
, aList
, and modifiers for navigating. Also, notice that the.on Move
modifier is applied to theForEach
struct:NavigationView{ List { ForEach(countries, id: \.self) { country in Text(country) } .on Move(perform: moveRow) } .navigationBarTitle("Countries", displayMode: .inline) .navigationBarItems(trailing: EditButton()) }
- Now, let's add the function that gets called when we try to move a row. The
moveRow
function should be located directly below the closing brace of the body view:private func moveRow(source: IndexSet, destination: Int){ countries.move(fromOffsets: source, toOffset: destination) }
Let's run our application in the canvas or a simulator and click on the edit button. If everything was done right, the preview should look as follows. Now, click and drag on the hamburger menu symbol at the right of each country to move it to a new location:
How it works…
To move list rows, you need to wrap the list in a NavigationView
, add the .on Move(perform:)
modifier to the ForEach
struct, and add a .navigationBarItems(..)
modifier to the list. The on Move
modifier calls the moveRow
function when clicked, while .navigationBarItem
displays the button that starts the "move mode," where list row items become movable.
The moveRow(source: IndexSet, destination: Int)
function takes two parameters, source
and IndexSet
, which represent the current index of the item to be moved and its destination index, respectively.