In todays tutorial we’re going to build a very simple list that you can search by using the filter in an Array. The concept is really quite simple, but good to also be aware of for when you might decide to filter on the frontend of the app.
Lets begin by creating a data model that will contain a published array:
class DataModel: ObservableObject {
@Published var items: [String] = [
"Ford", "Vauxhall", "Ferrari", "Lamborghini", "Aston Martin", "Nissan", "Bentley"
]
}
The DataModel we use is a class. We conform to the ObservableObject protocol and use the @Published property wrapper. If the array of strings called items is changed, then the @Published property wrapper will notify any view that uses this ObservableObject that a change has happend. The view will then update.
Our next task is to create the view and filter:
import SwiftUI
import Foundation
struct ContentView: View {
@State private var searchText = ""
@ObservedObject var dataModel = DataModel()
var filteredItems: [String] {
if searchText.isEmpty {
return dataModel.items
} else {
return dataModel.items.filter { $0.lowercased().contains(searchText.lowercased()) }
}
}
var body: some View {
NavigationView {
VStack {
TextField("Search Manufacturers", text: $searchText)
.padding()
.textFieldStyle(RoundedBorderTextFieldStyle())
.padding(.horizontal)
List(filteredItems, id: \.self) { item in
Text(item)
}
.navigationTitle("Manufacturer List")
}
}
}
}
Line 5 declares a private variable called searchText. It uses the @State property wrapper so that the view refreshes when a change occurs to the string.
Line 6 uses the @ObservedObject which in this case is the DataModel. Remember that we marked that as Observable, and on the view side we Observe it. When changes happen to the data model, the view is made aware and refreshes.
Lines 8 through 14 contain are used to filter with the searchText. We declare a variable called filteredItems. If the searchText is empty, we return the full dataModel.items array.
If there is searchText then we take the alternative path and use a filter on dataModel.items. Lets take a look at the syntax here:
dataModel.items is the array, in this case it holds car manufacturers.
.filter is a method that we are calling on the array.
In between the curly braces { } we have our condition. In this example:
$0.lowercased().contains(searchText.lowercased())
$0 is the first and only argument passed to the closure. This is each item in the array that arrives, one by one.
$0.lowercased() makes “Ford” into “ford”. .contains(searchText.lowercased()) checks to see if the argument “contains” the searchText that is also lowercased. In other words, you can search for Ford, ford, fo, or, rd, RD or whatever, and as both sides of the comparison are lowercased, the condition will be true and the item will not be filtered out. This repeats for each item in the array. With this being in a return, the final result is returned and filteredItems will contain only the items that contain the searchTerm.
Next we have our view starting on line 16 to the end of the block.
This has a navigation view followed by a VStack, and then a TextField where uses can perform the search. The text is $searchText which is the @State property wrapped variable mentioned earlier.
When typing in the box, the filteredItems is updated on each keystroke, and filtered accordingly.
On line 24 we have the List view working with the filteredItems. Each time it is updated, the view is redrawn.
Go ahead and test. This tutorial is really simple, but gives a good demonstration of how the array filter works and how easy SwiftUI makes it to keep the view refreshed with current data as you perform the search.
Leave a Reply
You must be logged in to post a comment.