In this article, we will learn how to create a search bar in SwiftUI.
Pre-requisites
- MacOS
- XCode
To create a SwiftUI project, follow the below steps.
Create a new project in XCode. Select iOS -> App -> Name your Project. Select Interface as SwiftUI and Language as Swift. Save the Project to a desired location.
Once you create the SwiftUI Project, you'll land on the ContentView file. Delete all the code inside the 'var body' loop.
So, let's start by creating a list of an array. I have created an array of numbers.
let numbers = ["One", "Two", "Three", "Four", "Five",
"Six", "Seven", "Eight", "Nine", "Ten",
"Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen",
"Sixteen", "Seventeen", "Eighteen", "Nineteen", "Twenty"]
Now, let's create a List by adding a NavigationStack and a List inside the NavigationStack. To learn more about NavigationStack, please refer to my article - Learn about Navigation in SwiftUI.
Add the following code inside the body loop.
NavigationStack {
List {
ForEach(numbers, id: \.self) {
number in
Text(number)
}
}
.navigationTitle("Numbers")
}
Once, you add this code, you can see the list formed with a navigation title 'Numbers' in the Canvas.
Now, we have the list ready. Now, let's add a search bar to our screen. To add the search bar, we will make use of '.searchable'
'.searchable' is used to configure the display of the search field.
@State private var searchText = ""
var body: some View {
NavigationStack {
List {
ForEach(numbers, id: \.self) {
number in
Text(number)
}
}
.navigationTitle("Numbers")
}
.searchable(text: $searchText)
The above code will make a search bar appear on our UI screen.
In the above code, we have created a variable called searchText and assigned it as a property wrapper 'State'.
Let's learn more about 'State'. SwiftUI manages the storage of any property you declare as a state. When its value changes, the view invalidates its appearance and recomputes the body. @State property wrapper allows us to modify the values inside a struct, which normally is not allowed as structs are value types.
The search bar gets a $searchText which indicates that there is a binding between the search bar and the searchText variable. As soon as we start typing in the search bar,the state property wrapper updates the searchText property.
Now, let's create another property to filter the results as per the text typed in the search bar.
var searchResult: [String] {
if searchText.isEmpty {
return numbers
} else {
return numbers.filter {
$0.contains(searchText)
}
}
}
Finally, we will link the search results with the searchable code. Modify the .searchable line with the following code.
.searchable(text: $searchText) {
ForEach(searchResult, id: \.self) {
result in
Text(result)
}
}
That's it! Run the code and watch the results!