One of the challenges from my learning code tasked us with adding a search bar to filter topic titles for further selection. The solution provided was a hideously complicated affair using many methods/functions and leveraging UIKit into SwiftUI. It was such a nightmarish solution that I’m surprised anyone actually used it.
On searching for alternatives, it became apparent that newer versions of iOS introduced a much more simpler method of implementing a search bar.
Solution
The ‘before’:
This is typical struct
displaying a list of content titles parsed from a JSON
file, contained within a NavigationView
, with NavigationLink
s that send the user to another screen. At this point, there is no search bar functionality.
Note: all elements shown in italics are project-specific properties/methods derived from elsewhere in the project code and will be different in your project.
struct ContentView: View {
@ObservedObject var model: DataUtils
var body: some View {
if model.jsonDataFile.count > 0 {
NavigationView {
List {
ForEach(model.jsonDataFile) { data in
NavigationLink(data.title,
destination: VideoScreen(video: data))
}
}
.navigationTitle(Text("All " + String(model.jsonDataFile.count) + " Videos"))
}
}
else {
ProgressView()
}
}
}
The ‘After’:
struct ContentView: View {
@ObservedObject var model: DataUtils
@State private var searchText = ""
var body: some View {
if model.jsonDataFile.count > 0 {
NavigationView {
List {
ForEach(searchResults) { data in
NavigationLink(data.title,
destination: VideoScreen(video: data))
}
}
.navigationTitle(Text("All " + String(model.jsonDataFile.count) + " Videos"))
}
.searchable(text: $searchText)
}
else {
ProgressView()
}
}
var searchResults: [DataModel] {
if searchText.isEmpty {
return model.jsonDataFile
} else {
return model.jsonDataFile.filter { $0.title.contains(searchText)}
}
}
}
The highlighted code
is all that’s needed for the searchbar to display and to function.