SearchBar with SwiftUI

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.