Table in SwifUI (II° Episode, search and select).

When using a table, you typically manage a lot of data, so some basic operations include searching and selecting. In this post, you’ll learn how to search for data in a table and how to select a row.

Search

Before we start, consider that our starting point is the code from Episode I, which you can obtain here .

The first step is to add the search functionality. To do this, we need to incorporate a NavigationStack into our code:

NavigationStack {
            Table(foundBeers, sortOrder: $sortOrder) {
                // the same code
            }.onAppear {
                Task {
                    await getBeers()
                }
            }.onChange(of: sortOrder) {
                beers.sort(using: sortOrder)
            }.searchable(text: $searchText, prompt: Text("Search by name"))
        }

Therefore, we added the searchable modifier (similar to how it’s done for a list). The searchText will contain the text entered by the user, and foundBeers will hold the results of the search.

var foundBeers: [Beer] {
        if searchText.count == 0 {
            return self.beers
        } else {
            return self.beers.filter({(beer: Beer) -> Bool in
                return beer.name.lowercased().contains(searchText.lowercased())
            })
        }
    }

If the search field is empty, this variable contains all the beers. Otherwise, it filters by name. The filter function retrieves all the beers that match the condition where the name contains the searchText – all in lowercase to avoid case sensitivity.

Combining the pieces:

struct ContentView: View {
    @State var beers: [Beer] = []
    @State var page = 0
    @State private var sortOrder = [KeyPathComparator(\Beer.name, order: .reverse)]
    @State private var searchText = ""

    var body: some View {
        NavigationStack {
            Table(foundBeers, sortOrder: $sortOrder) {
                TableColumn("Name", value: \.name)
                TableColumn("First Brew", value: \.first_brewed)
                TableColumn("ABV") { beer in
                    Text("\(beer.abv)")
                }
                TableColumn("Image") { beer in
                    AsyncImage(url: URL(string: beer.image_url)) { image in
                        image.resizable().scaledToFit()
                    } placeholder: {
                        ProgressView()
                    }
                    .frame(width: 100, height: 100)
                }
            }.onAppear {
                Task {
                    await getBeers()
                }
            }.onChange(of: sortOrder) {
                beers.sort(using: sortOrder)
            }.searchable(text: $searchText, prompt: Text("Search by name"))
        }
    }
    var foundBeers: [Beer] {
        if searchText.count == 0 {
            return self.beers
        } else {
            return self.beers.filter({(beer: Beer) -> Bool in
                return beer.name.lowercased().contains(searchText.lowercased())
            })
        }
    }
    
    func getBeers() async {
        // get from previous
    }
}

Select

To select and highlight an item, we need to make some minor changes:

  1. Add a variable that will contain the selected item or items.
  2. Use a different initialization function for the table.

For the first point:

@State private var beerSelected: Beer.ID?

Considering that there might be a selection or not, the beerSelected variable is optional (based on the identifiable property). If you want to enable multiple selections, replace Beer.ID? with an empty Set<Beer.ID>.

@State private var beerSelected: Set<Beer.ID> = Set<Beer.ID>()

For the second point on the list:

Table(beersSearched, selection: $beerSelected, sortOrder: $sortOrder) {

Please select the right beer!

Note: English is not my native language, so I apologize for any errors. I use AI solely to generate the banner of the post; the content is human-generated.

share this post with friends

Picture of Nicola De filippo

Nicola De filippo

I'm a software engineer who adds to the passion for technologies the wisdom and the experience without losing the wonder for the world. I love to create new projects and to help people and teams to improve

Leave a comment

Your email address will not be published. Required fields are marked *

Who I am

I'm a software engineer who adds to the passion for technologies the wisdom and the experience without losing the wonder for the world. I love to create new projects and to help people and teams to improve.

Follow Me Here

Get The Latest Updates

Periodically receive my super contents on coding and programming

join the family;)

Recent Posts