UISearchController Tutorial: Getting Started
In this tutorial, you’ll build a searchable Candy app based on a standard table view. You’ll add table view search capability, dynamic filtering and an optional scope bar using UISearchController, UISearchBar and friends. By Lorenzo Boaro.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
UISearchController Tutorial: Getting Started
20 mins
- Getting Started
- Populating the Table View
- Introducing UISearchController
- Setting Up searchController‘s Parameters
- Filtering With UISearchResultsUpdating
- Updating the Table View
- Sending Data to a Detail View
- Creating a Scope Bar to Filter Results
- Testing the Scope Bar
- Adding a Results Indicator
- Where to Go From Here?
Scrolling through massive lists of items can be a slow and frustrating process for users. When dealing with large datasets, it’s vitally important to let the user search for specific items. UIKit includes UISearchBar
, which seamlessly integrates with UINavigationItem
via a UISearchController
and allows for quick, responsive filtering of information.
In this tutorial, you’ll build a searchable Candy app based on a standard table view. You’ll add table view search capability, dynamic filtering and an optional scope bar, all while taking advantage of UISearchController
. In the end, you’ll know how to make your apps much more user-friendly and how to satisfy your users’ urgent demands.
Ready for some sugar-coated search results? Read on.
Getting Started
Start by downloading the starter project using the Download Materials button at the top or bottom of this tutorial. Once it’s downloaded, open CandySearch.xcodeproj in Xcode.
To keep you focused, the starter project has everything unrelated to searching and filtering already set up for you.
Open Main.storyboard and look at the view controllers contained within:
The view controller on the left is the root navigation controller of the app. Then you have:
- MasterViewController: This contains the table view that you’ll use to display and filter the candies you’re interested in.
- DetailViewController: This displays the details of the selected candy along with its image.
Build and run the app and you’ll see an empty list:
Back in Xcode, the file Candy.swift contains a struct to store the information about each piece of candy you’ll display. This struct has two properties:
-
name: This property has type
String
and is fairly self-explanatory. -
category: This is an
enum
of typeCandy.Category
, which represents the category each candy belongs to. It also conforms toRawRepresentable
so that you can convert it to and from an associated raw value of typeString
.
When the user searches for a type of candy in your app, you’ll search the name property using the user’s query string. The category will become important near the end of this tutorial, when you implement the scope bar.
Populating the Table View
Open MasterViewController.swift. You’ll manage all the different Candy
for your users to search in candies
. Speaking of which, it’s time to create some candy!
To populate candies
, add the following code to viewDidLoad()
after the call to super.viewDidLoad()
:
candies = Candy.candies()
Build and run. Since the sample project has already implemented the table view’s data source methods, you’ll see that you now have a working table view:
Selecting a row in the table will also display a detail view of the corresponding candy:
So much candy, so little time to find what you want! You need a UISearchBar
.
Introducing UISearchController
If you look at UISearchController
‘s documentation, you’ll discover it’s pretty lazy. It doesn’t do any of the work of searching at all. The class simply provides the standard interface that users have come to expect from their iOS apps.
UISearchController
communicates with a delegate protocol to let the rest of your app know what the user is doing. You have to write all of the actual functionality for string matching yourself.
Although this may seem scary at first, writing custom search functions gives you tight control over how your specific app returns results. Your users will appreciate searches that are intelligent and fast.
If you’ve worked with searching table views in iOS in the past, you may be familiar with UISearchDisplayController
. Since iOS 8, Apple has deprecated this class in favor of UISearchController
, which simplifies the entire search process.
In MasterViewController.swift, add a new property under candies
‘ declaration:
let searchController = UISearchController(searchResultsController: nil)
By initializing UISearchController
with a nil
value for searchResultsController
, you’re telling the search controller that you want to use the same view you’re searching to display the results. If you specify a different view controller here, the search controller will display the results in that view controller instead.
In order for MasterViewController
to respond to the search bar, it must implement UISearchResultsUpdating
. This protocol defines methods to update search results based on information the user enters into the search bar.
Still in MasterViewController.swift, add the following class extension outside of the main MasterViewController
:
extension MasterViewController: UISearchResultsUpdating {
func updateSearchResults(for searchController: UISearchController) {
// TODO
}
}
updateSearchResults(for:)
is the one and only method that your class must implement to conform to the UISearchResultsUpdating
protocol. You’ll fill in the details shortly.
Setting Up searchController
‘s Parameters
Next, you need to set up a few parameters for your searchController
. Still in MasterViewController.swift, add the following to viewDidLoad()
, just after the assignment to candies
:
// 1
searchController.searchResultsUpdater = self
// 2
searchController.obscuresBackgroundDuringPresentation = false
// 3
searchController.searchBar.placeholder = "Search Candies"
// 4
navigationItem.searchController = searchController
// 5
definesPresentationContext = true
Here’s a breakdown of what you’ve just added:
-
searchResultsUpdater
is a property onUISearchController
that conforms to the new protocol,UISearchResultsUpdating
. With this protocol,UISearchResultsUpdating
will inform your class of any text changes within theUISearchBar
. - By default,
UISearchController
obscures the view controller containing the information you’re searching. This is useful if you’re using another view controller for yoursearchResultsController
. In this instance, you’ve set the current view to show the results, so you don’t want to obscure your view. - Here, you set the placeholder to something that’s specific to this app.
- New for iOS 11, you add the
searchBar
to thenavigationItem
. This is necessary because Interface Builder is not yet compatible withUISearchController
. - Finally, by setting
definesPresentationContext
on your view controller totrue
, you ensure that the search bar doesn’t remain on the screen if the user navigates to another view controller while theUISearchController
is active.