Removing Items from SwiftUI Lists in Mac Apps

Most examples of removing items from SwiftUI lists use the .onDelete handler, which is not available for Mac apps. In this article I share what I learned to remove list items from SwiftUI Mac apps.

To remove items from SwiftUI lists in Mac apps, you must perform the following tasks:

  • Add a variable to the list view to store the selected list item.
  • If you are using a navigation link, supply a tag and selection when creating the link.
  • Make your struct or class conform to the Equatable and Hashable protocols.
  • Add the .onDeleteCommand handler to the list. The .onDeleteCommand handler is the handler SwiftUI Mac apps use to remove list items.

Add a Selection Variable to the List View

To remove an item from a SwiftUI list, the list view requires a variable to store the item you want to remove. Create an optional for the variable and set it to nil initially.

ListItemStruct is the name of the data structure in your app that you want to show in the list.

When you supply this selection when creating a navigation link, SwiftUI keeps track of the selected item in the list.

Most SwiftUI apps that use lists use a navigation link to create master-detail interfaces. Select an item from the list to show additional information in the detail view. Add a call to NavigationLink in the master view and set its destination to the detail view.

To support more complex selection behavior, you must supply two additional arguments to the navigation link call: tag and selection. Usually the tag is the current list item you’re adding to the list. The selection is the variable you added to the list view.

The following code demonstrates how to show a list of a book’s chapters:

This example uses the improved syntax Apple added in Xcode 13 to bind list text fields to items in an array. If you’re using Xcode 12 you will have to use a Text to display the titles and remove the $ character from $chapter.

Make Your Struct/Class Conform to Equatable and Hashable Protocols

To use the tag and selection arguments in a navigation link, your struct or class must conform to the Equatable and Hashable protocols. Your project won’t compile until you make the struct or class conform to those protocols.

Making your struct or class conform to Equatable requires you to implement the == operator to check for equality.

Replace Chapter with the name of your struct or class. Do whatever comparisons you need to make to determine that two objects are equal. SwiftUI list items require a unique ID. That’s what I used to determine equality in the example.

To conform to the Hashable protocol, you must implement the hash function.

Inside the hash function, call the hasher’s combine function for each property in your struct or class. Supply the name of the property.

Add the .onDeleteCommand Handler to the List

The last step is to remove the item from the list. Add the .onDeleteCommand handler to the list to enable the Delete menu item in the Edit menu. Inside the block of code, you will use the selection variable you added to the list view to find the selection index. Use the selection index to remove the item from the list.

The firstIndex function returns the first selected item in the list. After getting the index of the selected item, remove that item from the array that populates the list.

Now let’s put the whole list view together.

Removing an Item with a Button and the Delete Key

At this point you can remove a list item by choosing Edit > Delete. But you may want to provide a button to remove an item. How do you remove list items by clicking a button?

Start by moving the code inside the .onDeleteCommand handler into its own function. Moving the deletion code into a separate function will also make the list code cleaner.

Now the .onDeleteCommand handler looks like the following:

Call the function in your button. Add a .keyboardShortcut handler to the button to remove list items with the Delete (Backspace) key.

I haven’t figured out how to add a keyboard shortcut for the Delete menu item in the Edit menu. Every example I’ve seen on creating keyboard shortcuts for menu items in SwiftUI uses custom menu items, not the menu items that Apple supplies. I’ll update the article if I ever find a solution.

Sample Project

I have a project on GitHub that supports removing items from lists. Look at the PageListView.swift and Wiki.swift files for the list removal code.

Another sample project for SwiftUI list item removal is the Feed Read project by TrozWare for the Back to the Mac conference.