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)
You may override this by inserting the following prompt in the searchable view modifier:
.searchable(text: $textSearch, prompt: "Search text")
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 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.