Discover how one simple modifier can transform your app's search experience instantly!
Why Search with searchable modifier in iOS Swift? - Purpose & Use Cases
Imagine you have a long list of items in your app, like a contact list or a recipe book. Without a search feature, you have to scroll endlessly to find what you want.
Manually adding search means writing lots of code to filter the list, update the display, and handle user input. It's easy to make mistakes, and the app can feel slow or clunky.
The searchable modifier in SwiftUI lets you add a search bar with just one line of code. It automatically handles user input and filters your list smoothly and efficiently.
TextField("Search", text: $searchText) .filter { $0.contains(searchText) }
.searchable(text: $searchText)
You can quickly add powerful, user-friendly search to your app, making it easier for users to find exactly what they need.
Think about a shopping app where you want to find a specific product fast. With searchable, users can type a few letters and instantly see matching items.
Manual search is slow and complex to build.
searchable modifier simplifies adding search bars.
It improves user experience by making lists easy to search.
Practice
searchable modifier do in a SwiftUI view?Solution
Step 1: Understand the purpose of
Thesearchablesearchablemodifier adds a search bar UI element to a list or scroll view.Step 2: Identify its effect on content
It allows users to type text to filter or search through the displayed content.Final Answer:
Adds a search bar to filter content in lists or scroll views. -> Option DQuick Check:
searchable = search bar added [OK]
- Thinking searchable sorts items automatically
- Confusing searchable with styling modifiers
- Assuming searchable removes items without filtering
searchText?Solution
Step 1: Recall the searchable syntax
The searchable modifier requires a binding to a string, written astext: $variable.Step 2: Match the correct binding syntax
Using$searchTextpasses the binding, so the correct syntax is.searchable(text: $searchText).Final Answer:
.searchable(text: $searchText) -> Option CQuick Check:
Binding uses $ with variable name [OK]
- Omitting the text: label
- Not using $ for binding
- Passing variable without binding
struct ContentView: View {
@State private var searchText = ""
let fruits = ["Apple", "Banana", "Grape", "Apricot"]
var filteredFruits: [String] {
if searchText.isEmpty { return fruits }
return fruits.filter { $0.lowercased().contains(searchText.lowercased()) }
}
var body: some View {
List(filteredFruits, id: \.self) { fruit in
Text(fruit)
}
.searchable(text: $searchText)
}
}Solution
Step 1: Understand filtering logic
The filter checks if each fruit contains the search text "ap" ignoring case.Step 2: Apply filter to fruits list
"Apple" and "Apricot" contain "ap" (case-insensitive), "Banana" and "Grape" do not match exactly.Final Answer:
["Apple", "Apricot"] -> Option AQuick Check:
Filter by contains "ap" = Apple, Apricot [OK]
- Including fruits that don't contain "ap"
- Ignoring case sensitivity
- Returning full list regardless of search
struct ContentView: View {
@State var searchText = ""
let items = ["One", "Two", "Three"]
var filteredItems: [String] {
items.filter { $0.contains(searchText) }
}
var body: some View {
List(filteredItems, id: \.self) { item in
Text(item)
}
.searchable(text: searchText)
}
}Solution
Step 1: Check searchable binding syntax
The searchable modifier requires a binding, so it must betext: $searchText, nottext: searchText.Step 2: Verify other code parts
filteredItems is computed correctly, List accepts array with id, and searchText should be @State.Final Answer:
Missing $ to bind searchText in searchable modifier. -> Option AQuick Check:
Binding needs $ prefix [OK]
- Forgetting $ in searchable binding
- Making filteredItems @State unnecessarily
- Confusing List requirements
struct Contact: Identifiable {
let id = UUID()
let firstName: String
let lastName: String
}
struct ContentView: View {
@State private var searchText = ""
let contacts = [Contact(firstName: "John", lastName: "Doe"), Contact(firstName: "Jane", lastName: "Smith"), Contact(firstName: "Alice", lastName: "Johnson")]
var filteredContacts: [Contact] {
if searchText.isEmpty { return contacts }
return contacts.filter { contact in
contact.firstName.lowercased().contains(searchText.lowercased()) || contact.lastName.lowercased().contains(searchText.lowercased())
}
}
var body: some View {
List(filteredContacts) { contact in
Text("\(contact.firstName) \(contact.lastName)")
}
.searchable(text: $searchText)
}
}Solution
Step 1: Analyze filtering logic
The filter checks if either firstName or lastName contains the search text, ignoring case.Step 2: Confirm UI updates with searchable
The searchable modifier binds to$searchText, so typing updates the filteredContacts list dynamically.Final Answer:
Filters contacts by first or last name ignoring case and updates list dynamically. -> Option BQuick Check:
Filter by first or last name, case-insensitive [OK]
- Filtering only by first name
- Not using lowercased() causing case sensitivity
- Forgetting to bind searchText with $
Ready to prove it?
Pass the test and this pattern moves unknown
