From September 2021 is finally available native SwiftUI SearchBar component, so is not anymore necessary to attach UIKit things to have the search bar in a SwiftUI application, but there is a condition, can be restrictive for someone, to use iOS 15.
First look at a simple example, use the searchbar to search a string in a list of fruit.
struct SimpleSearchUIView: View { let names = ["Ananas", "Apple", "Pear", "Melon", "Banana"] @State private var searchText = "" var body: some View { NavigationView { List { ForEach(searchResults, id: \.self) { name in NavigationLink(destination: Text(name)) { Text(name) } } } .searchable(text: $searchText) .navigationTitle("Fruits") } } var searchResults: [String] { if searchText.isEmpty { return names } else { return names.filter {$0.lowercased().contains(searchText.lowercased())} } } }
First thing, add a searchable to a List. The searchable is waiting for a text, and the written text is saved in a state variable, in this case, searchText.
The ForEach is not working on a list but with a variable that contains the fruits filtered using the search text. Simply it applies a filter on the names array.
Now see an example using an array of complex type, simply Post type, so defined:
struct Post: Identifiable, Hashable { var id = UUID() var title: String var image: String }
Now the List and the searchbar working in this way:
struct SerarchUIView: View { @State private var searchText = "" var posts = [ Post(title: "Toolbar and Customization", author: "Nicola De Filippo"), Post(title: "SwiftUI App Chat – Episode II°", author: "Nicola De Filippo"), Post(title: "SwiftUI App Chat – Episode I°", author: "Nicola De Filippo"), Post(title: "Navigation", author: "NDF"), Post(title: "SwiftUI App Chat – Episode II°", author: "Nicola De Filippo"), Post(title: "List in SwiftUI", author: "NDF"), Post(title: "State, Binding and Refactoring", author: "Nicola De Filippo") ] var body: some View { NavigationView { List(searchResults) { post in VStack(alignment: .leading) { Text(post.title) .font(.headline) Text(post.author) .font(.caption) } }.searchable(text: $searchText) .navigationBarTitle("My posts", displayMode: .automatic) } } var searchResults: [Post] { if searchText.isEmpty { return posts } else { return posts.filter { (post: Post) in return post.title.lowercased().contains(searchText.lowercased()) } } } }
Now the list iterates on a list of posts, the searchable works with a text, instead of the search result in this case filter the array using the title. If everything is ok, you should have:
Note: English is not my native language, so I’m sorry for some errors. I appreciate it if your correct me.
6 comments
I do trust all the ideas you’ve presented in your post. They are really convincing and will definitely work. Nonetheless, the posts are too short for newbies. May just you please lengthen them a bit from next time? Thank you for the post.
Thanks for your feedback, I appreciated it a lot! In the next posts, I’ll try to do better.
Muchas gracias por la informacion. Un cordial saludo. Saludos.
Muy buen articulo. muy recomendable! Reciba un cordial saludo!
Gracias por tu aportacion. Gracias por compartirlo. Un cordial saludo!
Muy buen post. Un cordial saludo. Un cordial saludo!