Reading time: 2 min

This tutorial shows you how to create a search bar in SwiftUI. There are two ways of doing it:

  1. Create a custom view, which works on any SwiftUI Version.
  2. Use the searchable modifier, introduced in Swift 3.

Custom Search Bar View

The end result will look something like this:

Search bar in SwitUI

The search bar has a button to clear its content, as well as to hide itself with the Cancel button.

struct SearchBar: View {
    @Binding var isShowing: Bool // determines visibility
    @Binding var text: String // the inputted search text
    @State private var isEditing = false

    var body: some View {
        Group {
            // If the bar should be shown, render it, otherwise
            // use an EmptyView
            if isShowing {
                HStack {
                    TextField("Search...", text: $text)
                        .padding(.horizontal, 25)
                        .overlay(HStack { // Add the search icon to the left
                            Image(systemName: "magnifyingglass")
                                .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
                                .padding(.leading, 8)

                            // If the search field is focused, add the clear (X) button
                            if isEditing {
                                Button(action: {
                                    self.text = ""
                                }) {
                                    Image(systemName: "")
                                        .padding(.trailing, 8)
                        }).padding(.horizontal, 10)
                        .onTapGesture {
                            self.isEditing = true

                    // If the search field is focused, render the "Cancel" button
                    // to the right that hides the search bar altogether
                    if isEditing {
                        Button(action: {
                            self.isEditing = false
                            self.text = ""
                            self.isShowing = false
                            // Dismiss the keyboard
                            UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
                        }) {
                        }.padding(.trailing, 10)
                        .transition(.move(edge: .trailing))
            } else {

Searchable Modifier

The end result looks like this:


This code works starting SwiftUI 3 (iOS 15, macOS 12).

The recipe goes as follows:

  1. Add the searchable modifier to your view, which must be embedded in a NavigationView.
  2. Specify the String binding for the search text, the search bar placement and its prompt.
  3. Optionally specify a list of search suggestions, marking each entry view with searchCompletion.

Here's the code for the example above:

let animals = ["Hare", "Tortoise", "Ant", "Ladybug"]
@State private var searchText = ""

var filteredAnimals: [String] {
    ? animals
    : animals.filter { $0.lowercased().contains(searchText.lowercased()) }

var body: some View {
  NavigationView {
    List(filteredAnimals, id: \.self) { animal in
      label(for: animal)
    .searchable(text: $searchText,
                  placement: .toolbar,
                  prompt: "Search...") {
      ForEach(animals, id: \.self) { animal in
        label(for: animal)

private func label(for animal: String) -> some View {
  Label(animal, systemImage: animal.lowercased())

On iOS, the searchable placement parameter doesn't seem to have much effect.

Next Post Previous Post