Oct 15, 2022 iOS

How to use Swiftui searchable

The SwiftUI searchable () tweak adds a search bar directly to a NavigationView, which will either remain fixed for simple layouts or appear and scroll when used with a list.

Prior to iOS 15, SwiftUI did not have a built-in modifier for handling search in List displays. Developers must provide your own solution. We’ve created a tutorial that teaches you how to utilise TextField in SwiftUI to construct a search bar and display the results. With the release of iOS 15, the SwiftUI framework provides a new searchable enhancement to List displays.

This may be as easy as adding searchable() to some view within a navigation view, as demonstrated below:

The Modifier for SwiftUI Searchable Views

Before we can add search to our list, we need a state variable to contain our search query text:

The.searchable view modification is then applied to our content view. You may apply the change to any content view; you are not limited to utilising it only while searching lists:

    @State private var textSearch = ""

Finally, in response to a change in the query string, we adjust our fetch request to return new results:

NavigationView {
            Text("Searching for \(textSearch)")
                .searchable(text: $textSearch)
        }

Text placeholder

The following prompt is presented in the search area by default:

.searchable(text: $textSearch)
Swiftui Searchable
SwiftUI Searchable

You may override this by inserting the following prompt in the searchable view modifier:

 .searchable(text: $textSearch, prompt: "Search text")
Swiftui Searchable
Swiftui Searchable

By combining all of the code, we obtain

struct SearchView: View {
    @State private var textSearch = ""

    var body: some View {
        NavigationView {
            Text("Searching for \(textSearch)")
                .searchable(text: $textSearch, prompt: "Search text")
                .navigationTitle("Search Text")
        }
    }
}
Swiftui Searchable
SwiftUI Searchable

SwiftUI provides built-in support for search functionality through the searchable modifier.

To add search functionality to a view, you can add the searchable modifier to the view and specify a search scope. Here’s an example:

struct MyView: View {
    @State private var searchText = ""
    
    var body: some View {
        NavigationView {
            List {
                // List items
            }
            .searchable(text: $searchText) {  // <-- Add searchable modifier
                Text("Search")
            }
            .navigationTitle("My List")
        }
    }
}

In this example, the List view is made searchable by adding the searchable modifier. The first parameter of the searchable modifier is a binding to the search text, which is stored in a @State variable called searchText. The second parameter is a closure that specifies the search scope, which is a Text view with the string “Search” in this example.

When the user enters text in the search bar, the searchText variable is updated with the search text. You can use this variable to filter your list items based on the search text. For example, you can use the filter() method to filter your list items.

struct MyView: View {
    @State private var searchText = ""
    let items = ["Apple", "Banana", "Cherry", "Durian", "Elderberry"]
    
    var body: some View {
        NavigationView {
            List {
                ForEach(items.filter({ searchText.isEmpty || $0.localizedStandardContains(searchText) })) { item in
                    Text(item)
                }
            }
            .searchable(text: $searchText) {
                Text("Search")
            }
            .navigationTitle("My List")
        }
    }
}

In this example, the list items are filtered based on whether they contain the search text. The filter() method is called on the items array, and the closure passed to filter() checks whether the search text is empty or whether the item contains the search text using the localizedStandardContains(_:) method. The resulting filtered array is then used in a ForEach loop to display the filtered list items.

struct ContentView: View {
    @State private var searchText = ""

    var body: some View {
        NavigationView {
            List {
                ForEach(getFilteredData()) { data in
                    Text(data)
                }
            }
            .navigationTitle("Searchable List")
            .searchable(text: $searchText) {
                ForEach(getFilteredData()) { data in
                    Text("Search for \(data)")
                        .searchCompletion(data)
                }
            }
        }
    }

    func getFilteredData() -> [String] {
        if searchText.isEmpty {
            return ["Apple", "Banana", "Cherry", "Grape", "Kiwi", "Lemon", "Mango"]
        } else {
            return ["Apple", "Banana", "Cherry", "Grape", "Kiwi", "Lemon", "Mango"]
                .filter { $0.localizedCaseInsensitiveContains(searchText) }
        }
    }
}

In this example, we have a List that displays some data. We have added the searchable modifier to the List, passing in a closure that returns a list of search completions. Whenever the user types in the search bar, the searchText variable is updated with the search query, and the getFilteredData function is called to filter the data based on the search query.

Note that in order to use the searchable modifier, you need to embed your view in a NavigationView. Also, you can customize the search bar by using the searchable modifier’s placement parameter. By default, the search bar is displayed at the top of the view, but you can also display it as a navigation bar item or as a toolbar item.

Index