UIKit Searching with UISearchController & UISearchBar

Posted by Mark Wright on Thu 12 April 2018

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

  1. Use UISearchController when you want search in a UINavigationItem or a UITableView.tableHeaderView
  2. Don't apply AutoLayout constraints to a UISearchBar owned by a UISearchController.
  3. 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 a UISearchBar by itself.
  4. Example Code

The Details

There are three common ways people implement a searching interface:

  1. Add a UISearchBar to the current UINavigationItem. This option is pretty easy these days. Create a UISearchController and add it to UINavigationItem.searchController. It works as you would expect.

  2. Add a UISearchBar to a UITableView.tableHeaderView. This option is also pretty easy. Create a UISearchController and add its searchBar to the UITableView.tableHeaderView. It mostly works as you would expect.

  3. Add a UISearchBar to some other view in your view hierarchy. This option can run into problems. On the surface it seems simple. Create a UISearchController and add its searchBar 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 UISearchBar in a content view

Content obscured by UISearchController 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

tags: ios


Comments !