Skip to content

Mastering Search (SwiftUI)

A SwiftUI guide for coding agents. Also covers searchable modifier, search bar placement, search suggestions completion, issearching dismisssearch, search scopes segmented, search tokens.

The searchable modifier (iOS 15+) adds a system search bar wherever the platform expects one: in the master column on iOS and iPadOS, in the trailing toolbar on macOS. You provide a text binding and react to it; suggestions, scopes, and tokens layer on top.

Wiring the Query

Attach searchable to the NavigationView or NavigationStack and drive requests from the binding. The placement parameter (automatic, sidebar, toolbar, navigationBarDrawer) is a suggestion SwiftUI may ignore.

NavigationView {
  List(viewModel.repos) { repo in
    RepoRow(repo: repo)
  }
  .searchable(text: $query, prompt: Text("Search"))
  .onChange(of: query) { newQuery in
    Task { await viewModel.search(matching: newQuery) }
  }
}

searchable(text:isPresented:) adds programmatic control over whether the search field is active.

Reacting to Search State

Two environment values work inside any view under a searchable modifier, and only there: isSearching says whether the user is interacting with the search bar, and dismissSearch ends the interaction. Typical use: overlay quick results while searching.

@Environment(\.isSearching) var isSearching
@Environment(\.dismissSearch) var dismissSearch

.overlay {
  if isSearching && !query.isEmpty {
    SearchResultView(query: query)
  }
}

Suggestions, Scopes, Tokens

searchSuggestions shows a suggestion list; searchCompletion turns a row into a button that fills the query. Apply searchCompletion only to non-interactive views such as Text or Label, because it wraps its content in a Button.

.searchSuggestions {
  ForEach(suggestions, id: \.self) { suggestion in
    Text(suggestion)
      .searchCompletion(suggestion)
  }
}

searchScopes($scope) { ... } renders a segmented control under the bar (iOS 16+). Token fields come from the searchable(text:tokens:suggestedTokens:) overload: tapping a suggested token moves it into the bar and into the selected-tokens binding, and you can also append tokens yourself by parsing the query in onChange.

Use this guidance in your coding agent

Install the Better Design MCP once. Your agent then loads this page with one call.

get-swiftui-guide({ topic: "swiftui-mastering-search" })
claude mcp add --scope user better-design --transport http https://better-design.com/api/mcp --header "Authorization: Bearer <YOUR_API_KEY>"
Browse related design systems