Last Updated: November 19, 2020
·
9.106K
· mozharovsky

Search mechanism in iOS 8

The search mechanism has been updated since iOS 8 release, so I decided to explore it myself and share with others my experience.

To begin with, I'd like to overview the architecture of search mechanism in iOS. Basically, it represents a search bar where you type somewhat you're looking for. Inside of that search bar lies its controller as well as everything in iOS it follows MVC model. The search controller manages the process of search.

<b>Part 1.</b>

Now let's take a look at how it's presented.

1) You've got a data (let's say it's inside a table view). I decided it to be some cities I'm going to visit. :P

Picture

2) We need a quick search. For that we add a search bar above of the table view. (I'll explain how to make it in code)

Picture

We have got a search bar. But what's next? When you click on a text view inside of the search bar a program shows you a stage view (a darken one) until you type anything. Once you've typed something the search process started! It's being managed by a search controller (later, in code we will cover that aspect). Before we move further, think of how the search controller shows results of the search.

The answer is simple - it requires an external table view with its controller. Thus, there will be at least 2 table views in our app.

3) With that said, here is a picture of how to looks like. You simply type what you're looking for in a search bar and its controller presents a table view with results of your search.

Picture

<b>Part 2.</b>

Now we're going to implement a search mechanism in code. I've already prepared the code which you can find in my repo on GitHub (link is on the bottom of this article) but we will overview some important aspects.

1) <b>UISearchController</b>. It's a new type we've got with iOS 8 release. You don't have to add a search bar in IB manually, of course if it's not a custom one. In fact, you don't add anything in IB but your initial table view.

Create 2 variables for a search controller and its results controller (which is a UITableViewController).

var searchController: UISearchController?
var searchResultsController: UITableViewController?

Now it's time to setup our search controller. Go to <b>viewDidLoad()</b> method and add the following lines of code.

// A table for search results and its controller.
let resultsTableView = UITableView(frame: self.tableView.frame)
self.searchResultsController = UITableViewController()
self.searchResultsController?.tableView = resultsTableView
        self.searchResultsController?.tableView.dataSource = self
self.searchResultsController?.tableView.delegate = self

// Register cell class for the identifier.
self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: self.identifier)
        self.searchResultsController?.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: self.identifier)

self.searchController = UISearchController(searchResultsController: self.searchResultsController!)
self.searchController?.searchResultsUpdater = self
self.searchController?.delegate = self
self.searchController?.searchBar.sizeToFit() // bar size
self.tableView.tableHeaderView = self.searchController?.searchBar

self.definesPresentationContext = true

We assign a created search bar to the <b>tableHeaderView</b> property of our main table view. So is moves as its table moves. Also you may have already seen the feature I've added in this demo app in other apps, when your main table view appears its search bar is initially hidden. But if you scroll it down - voila, it's got back. Very simple and neat.

This function manages the feature I've just described.

func hideSearchBar() {
     let yOffset =   self.navigationController!.navigationBar.bounds.height +        UIApplication.sharedApplication().statusBarFrame.height
     self.tableView.contentOffset = CGPointMake(0, self.searchController!.searchBar.bounds.height - yOffset)
}

We simply set the start point for a table view's content.

2) A results' table view setup and management.

I decided to use the same instance of a view controller for both results' table view and our main table view, so I added the following check for figuring out which table view we're working with.

if tableView == self.searchResultsController?.tableView {
     // todo: add content for results' table view
} else {
     // todo: add content for a main table view
}

If you check out the code I published on GitHub, you'll find how a working example looks. :)

3) Results updating.

Once you type anything in a search bar's text field, your search controller must do a specific stuff for finding a result with the input (a simple text). I've used a predicate for filtering my array with cities. A predicate is already provided by Apple as <b>NSPredicate</b> class. You can either use a block for filtering or use a string filter (pattern). For our search it was better to apply a predicate with a block.

You must implement <b>UISearchResultsUpdating</b> protocol and set a <b>searchResultsUpdater</b> property (a delegate).

Then go to <b>updateSearchResultsForSearchController(searchController: UISearchController)</b> function and add the logic of searching.

For creating a predicate add the following code.

let searchBarText = self.searchController!.searchBar.text

let predicate = NSPredicate(block: { (city: AnyObject!, b: [NSObject : AnyObject]!) -> Bool in
     var range: NSRange = 0
     if city is NSString {
        range = city.rangeOfString(searchBarText, options: NSStringCompareOptions.CaseInsensitiveSearch)
      }

      return range.location != NSNotFound
})

After creating a predicate, filter an array with data and reload a table view with results.

// Get results from predicate and add them to the appropriate array.
let filteredArray = (self.cities as NSArray).filteredArrayUsingPredicate(predicate)
self.results?.addObjectsFromArray(filteredArray)

// Reload a table with results.         self.searchResultsController?.tableView.reloadData()

And that's it! :)

Summarizing all said above, we have got a pretty big overview of how a search mechanism works in iOS 8. I hope you like it, stay with me and more overviews come!

<b>Links</b>:

<a href="https://github.com/Mozharovsky/iOS-Demos/tree/master/Search%20Mechanism">GitHub (with source code)</a>

<a href="http://bohemiancoding.com/sketch/">Sketch 3 (a software I used for making pics)</a>

<a href="http://icons8.com">neat icons</a>

Related protips:

Some simple Swift Extensions (Strip HTML, RGB Color, Color invert, Dismiss modal segue)