SwiftUI Delete Multiple Rows from List Tutorial

A single item can be easily deleted when swiping a row from a list. When multiple rows must be deleted from a list some additional work needs to be done when the list is in Edit mode. In this tutorial a list of numbers will be displayed, where multiple rows can be deleted in the live preview. SwiftUI requires Xcode 11 and MacOS Catalina, which can be downloaded at the Apple developer portal.

Open Xcode and either click Create a new Xcode project in Xcode’s startup window, or choose File > New > Project. In the template selector, select iOS as the platform, select the Single View App template, and then click Next. Enter SwiftUIDeleteMultipleRowsListTutorial as the Product Name, select the Use SwiftUI checkbox, and click Next. Choose a location to save the project on your Mac.

swiftui-delete-multiple-rows-project.png

In the canvas, click Resume to display the preview. If the canvas isn’t visible, select Editor > Editor and Canvas to show it.

resume-update-preview.png

In the Project navigator, click to select ContentView.swift. Add the following properties inside the ContentView struct

@State var numbers = ["One","Two","Three","Four","Five","Six","Seven","Eight","Nine","Ten"]
@State var editMode = EditMode.inactive
@State var selection = Set<String>()

The numbers property contain the row data. The editMode will toggle between active and inactive state and the selection property is needed to enable multiple selection of rows. Next, change the body variable to

var body: some View {
    // 1.
    NavigationView {
        List(selection: $selection) {
            ForEach(numbers, id: \.self) { number in
                Text(number)
            }
        }
         // 2.
        .navigationBarItems(leading: deleteButton, trailing: editButton)
         // 3.
        .environment(\.editMode, self.$editMode)
    }
}
  1. The List containing the numbers is displayed.

  2. The delete and edit buttons are declared by separate views

  3. The editMode binding sets the environment value.

Next, add the editButton View

private var editButton: some View {
    if editMode == .inactive {
        return Button(action: {
            self.editMode = .active
            self.selection = Set<String>()
        }) {
            Text("Edit")
        }
    }
    else {
        return Button(action: {
            self.editMode = .inactive
            self.selection = Set<String>()
        }) {
            Text("Done")
        }
    }
}

The Title of the Edit button is changed from “Edit” to “Done” dependent of the current state of the editmode. Next, add the

private var deleteButton: some View {
    if editMode == .inactive {
        return Button(action: {}) {
            Image(systemName: "")
        }
    } else {
        return Button(action: deleteNumbers) {
            Image(systemName: "trash")
        }
    }
}

The Trash button is displayed only when in the active edit mode. When the trash button is selected the deleteNumbers method will be called.

private func deleteNumbers() {
    for id in selection {
        if let index = numbers.lastIndex(where: { $0 == id })  {
            numbers.remove(at: index)
        }
    }
    selection = Set<String>()
}

The selected items will be removed., where the last row will be deleted first. This is to always ensure items will be deleted cleanly in the array.

Go to the preview window and choose Live Preview. Select the Edit button and select a few rows in the List. Select the Trash button and next the Done button. The Rows are removed from the List which is updated in the preview.

swiftui-delete-multiple-rows-preview.png

The source code of the SwiftUIDeleteMultipleRowsListTutorial can be downloaded at the ioscreator repository on Github.

Source: ioscreator.com

SwiftUI Delete Multiple Rows from List Tutorial