UIKit includes UISearchBar
and UISearchController
to help you build search features. They are simple APIs but it isn't clear (at least it wasn't to me) that UISearchController
isn't always the right choice.
TL;DR
- Use
UISearchController
when you want search in aUINavigationItem
or aUITableView.tableHeaderView
- Don't apply AutoLayout constraints to a
UISearchBar
owned by aUISearchController
. - If you want precise control over how the search bar moves when it becomes first responder and how the results are displayed don't use
UISearchController
use aUISearchBar
by itself. - Example Code
The Details
There are three common ways people implement a searching interface:
-
Add a
UISearchBar
to the currentUINavigationItem
. This option is pretty easy these days. Create aUISearchController
and add it toUINavigationItem.searchController
. It works as you would expect. -
Add a
UISearchBar
to aUITableView.tableHeaderView
. This option is also pretty easy. Create aUISearchController
and add itssearchBar
to theUITableView.tableHeaderView
. It mostly works as you would expect. -
Add a
UISearchBar
to some other view in your view hierarchy. This option can run into problems. On the surface it seems simple. Create aUISearchController
and add itssearchBar
to your view hierarchy. However, it generally doesn't work the way you would expect.
The first and second options above work pretty well and are clearly the scenarios for which UISearchController was designed. Problems arise when you try to implement the third scenario because of the behavior of UISearchController
. When the textField
in the UISearchBar
becomes the first responder its owning UISearchController
removes it from its existing superview and adds it to its own view hierarchy. If you have constrained the search bar directly this can confuse AutoLayout. It often causes the search bar to move off to the left side of the screen but the exact behavior depends on the constraints.
You can put the search bar in a container view and constrain the container view. As long as you aren't relying on the search bar to define the height of the container view it will solve the positioning problem. However, it won't look right because UISearchController
presents itself modally and obscures the rest of your interface. This is usally what you want if the search bar is in the navigation item or a table header but not if you have the search bar in the middle of your view. For example:
UISearchBar in a content view
Content obscured by UISearchController
The solution is to use a UISearchBar
directly and implement its delegate. Forget about UISearchController
. You are free to constrain the search bar however you want and can decide exactly what happens when the user interacts with it.
I have created a small project that implements searching in a navigation item, a table header, inside a container view with a UISearchController
, and inside a container view without a UISearchController
.
The code is on github
Cover photo of a Female Osmia Conjuncta Bee
Comments !