Always show search bar in a navigation bar in SwiftUI
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.
Default Behavior
By default, the search bar is hidden under the navigation title and visible only when a user pulls down the content.
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
SwiftUI
NavigationView {
List {
...
}
.listStyle(.plain)
.navigationTitle("SwiftUI")
}
.searchable(text: $queryString) {
...
}
A plain list-style would yield the same behavior on SwiftUI.
You can easily support sarunw.com by checking out this sponsor.
AI Grammar: Correct grammar, spell check, check punctuation, and parphrase.
Always Show Search Bar
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.
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.
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 Share4 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.
Dynamic button configuration in iOS 15
Learn how to change button configuration, e.g., title and color, based on the internal and external changes.