Mastering SwiftUI: Creating a Search Bar with Ease
Written on
Introduction to Searchable in SwiftUI
In earlier versions of iOS, specifically prior to iOS 15, SwiftUI lacked a built-in search modifier. Developers often had to manually implement search functionality using a TextField and create separate views to display the results. However, with the transition to iOS 15, a more streamlined approach has emerged, allowing for the creation of a search bar using the searchable modifier.
This tutorial is part of my ongoing SwiftUI series. Here, we will apply the searchable modifier to a ForEach List View, as illustrated in the accompanying images. You can either create a new project or utilize an existing one for practice. For detailed instructions on how to set up a project, follow this link.
Designing the User Interface
This guide assumes you are familiar with ForEach Lists and NavigationView. If you are new to these topics, I recommend reviewing the linked tutorials for a comprehensive understanding.
To begin, we will define the structures that will manage the content. Write the following code outside of ContentView:
struct Collections: Identifiable {
var id = UUID()
var name: String
var image: String
}
Next, we will establish a variable to store the collection values. Place this code right below the struct Collections definition:
var collections = [
Collections(name: "Humanity", image: "person.fill"),
Collections(name: "Wild Life", image: "pawprint.fill"),
Collections(name: "Global", image: "globe.asia.australia.fill"),
Collections(name: "Energy", image: "bolt.fill"),
Collections(name: "Nature", image: "leaf.fill"),
Collections(name: "Weather", image: "cloud.drizzle.fill"),
Collections(name: "Travel", image: "airplane"),
Collections(name: "Video Games", image: "gamecontroller.fill"),
Collections(name: "Health", image: "heart.fill")
]
Now, let’s design how each row will appear. Use the following code:
struct ImageLabelRow: View {
var collection: Collections
var body: some View {
HStack {
Image(systemName: collection.image)
.font(.system(size: 75))
.padding()
Text(collection.name)
.font(.system(.largeTitle, design: .rounded))
.fontWeight(.black)
}
}
}
This is a visual representation of our current source code:
Now, let's implement the list within ContentView. Use the following code snippet:
struct ContentView: View {
@State var searchCollection = collections
var body: some View {
NavigationView {
List(searchCollection) { index in
ImageLabelRow(collection: index)}
.navigationTitle("Select a Topic")
}
}
}
At this stage, the app should resemble the following design:
Integrating the Search Bar
Next, we will incorporate the search bar using the searchable modifier. Create a variable inside ContentView to hold the search keyword:
@State private var searchText = ""
By default, the search bar on an iPhone is positioned beneath the navigation title. To add the searchable modifier, include it just below NavigationView:
.searchable(text: $searchText)
The code should now look like this:
Run the application, and you may need to scroll up to see the search bar. To enhance user experience by keeping it always visible, modify the searchable code like this:
.searchable(text: $searchText, placement: .navigationBarDrawer(displayMode: .always))
Now the user interface is more user-friendly.
Implementing Search Functionality
We now have the search bar, but it doesn’t yet perform any searches. We will use the onChange modifier to implement this functionality. Add the following code just below the .searchable modifier:
.onChange(of: searchText) { index in
if !index.isEmpty {
searchCollection = collections.filter { $0.name.contains(index) }} else {
searchCollection = collections}
}
The onChange modifier triggers an action every time the value changes. We placed it under NavigationView since that’s where all search activities occur. This code filters the contents of the collections variable based on the input in the search bar. The $0 refers to the first argument of the name.
Here’s the final source code for ContentView:
Run the application to test the search functionality by entering values that exist in the app, as well as those that don’t. For instance, searching for items starting with the letter H should yield results.
Congratulations! You’ve successfully added searchable capabilities to your app. For the complete source code, click this link.
May the code be with you,
- Arc
This video demonstrates how to implement a search bar in SwiftUI using the new searchable modifier.
Learn how to effectively work with the searchable modifier in your iOS and macOS apps with this comprehensive guide.