Always show search bar in a navigation bar in SwiftUI

⋅ 2 min read ⋅ SwiftUI searchable

Table of Contents

In SwiftUI 3, we finally have a UISearchController equivalent in SwiftUI. But with a declarative nature, some setting that we can easily do in UIKit isn't obvious in SwiftUI. Today, I'm going to show you how to control search bar visibility on scrolling.

You can easily support sarunw.com by checking out this sponsor.

Sponsor sarunw.com and reach thousands of iOS developers.

Default Behavior

By default, the search bar is hidden under the navigation title and visible only when a user pulls down the content.

Left: The search bar hidden under the navigation title. Right: Pull down to reveal the search bar.
Left: The search bar hidden under the navigation title. Right: Pull down to reveal the search bar.

When you scroll down, the search bar collapses into the navigation bar. This is the behavior for both UISearchControl in UIKit and searchable in SwiftUI.

UIKit

let searchController = UISearchController(searchResultsController: nil)
navigationItem.searchController = searchController
Default behavior of navigation view with search control.
Default behavior of navigation view with search control.

SwiftUI

NavigationView {
List {
...
}
.listStyle(.plain)
.navigationTitle("SwiftUI")
}
.searchable(text: $queryString) {
...
}

A plain list-style would yield the same behavior on SwiftUI.

Default behavior of navigation view with search control in SwiftUI.
Default behavior of navigation view with search control in SwiftUI.

You can easily support sarunw.com by checking out this sponsor.

Sponsor sarunw.com and reach thousands of iOS developers.

To force the search bar to always show in UIKit, we set navigation item instance property hidesSearchBarWhenScrolling to false.

UIKit

With this simple change, the search bar will always show.

let searchController = UISearchController(searchResultsController: nil)
navigationItem.hidesSearchBarWhenScrolling = false
navigationItem.searchController = searchController

Search bar visible on first loaded and stay there even when users scroll down.

hidesSearchBarWhenScrolling equals false make search bar always show.
hidesSearchBarWhenScrolling equals false make search bar always show.

SwiftUI

To get this same behaviour in SwiftUI, we have to set placement parameter in searchable modifier to .navigationBarDrawer(displayMode: .always).

NavigationView {
List {
...
}
.listStyle(.plain)
.navigationTitle("SwiftUI")
}
.searchable(text: $queryString, placement: .navigationBarDrawer(displayMode: .always)) {
...
}

Navigation Bar Drawer placement (.navigationBarDrawer) tells SwiftUI that we want to place the search bar beneath the navigation bar title, and .always display mode means we want it to stay there without collapse into the navigation bar.

With this change, you will get similar behavior as UIKit.

.navigationBarDrawer(displayMode: .always)
.navigationBarDrawer(displayMode: .always)

Caveat

We have a minor behavior difference here.

  • UIKit with hidesSearchBarWhenScrolling = false starts with a navigation bar in large title state.
  • SwiftUI with .navigationBarDrawer(displayMode: .always) starts with a navigation bar in a inline title state. You still get a large title when you pull the content down. The only difference is the initial state of the title.

Read more article about SwiftUI, searchable, or see all available topic

Enjoy the read?

If you enjoy this article, you can subscribe to the weekly newsletter.
Every Friday, you'll get a quick recap of all articles and tips posted on this site. No strings attached. Unsubscribe anytime.

Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.

If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.

Become a patron Buy me a coffee Tweet Share
Previous
4 Xcode shortcuts to get back your screen space

Working on your MacBook without an external monitor can be troublesome due to the small screen size. I will show you 4 Xcode shortcuts that might mitigate the situation.

Next
Dynamic button configuration in iOS 15

Learn how to change button configuration, e.g., title and color, based on the internal and external changes.

← Home