Add Searchbar to TableView

Most modern iOS apps have a feature of a search bar to search for items in a Table View. This tutorial will show how to add a search bar to a Table View which let the user search through the items by specifying a search term.

Update: Feb 25, 2014. This tutorial is made with Xcode 4 and targeted for iOS 6. The updated version for iOS7 and Xcode 5 is available here.
Update: Feb 9, 2015. The rewritten version in Swift for iOS 8.1 and Xcode 6.1 is available here.

Open Xcode and create a new Single View Application. For product name, use SearchTableViewDemo and then fill out the Organization Name, Company Identifier and Class Prefix fields with your customary values. Make sure only iPhone is selected in Devices, and that the Use Storyboards checkbox and Use Automatic Reference Counting checkbox are selected.

Go to the MainStoryboard file, delete the Existing View Controller and drag a new TableView Controller to the canvas. Select the TableView Controller and In the Editor menu choose "Embed in Navigation Controller". This will put a Navigation Controller around the TableView Controller.

Next, Add a New Objective-C class to the project, make it a subview of UITableViewController and name it SearchViewController. in SearchViewController.m add the following property in the @interface section.

@interface SearchViewController ()

@property (nonatomic, strong) NSMutableArray *tableData;

@end

In viewDidLoad we fill the array with numbers.

- (void)viewDidLoad
{
  [super viewDidLoad];

  self.tableData = [@[@"One",@"Two",@"Three",@"Twenty-one"] mutableCopy;]
}

When we added our SearchViewController class some methods are created from the TableViewController template. Next, we must finetune some of this methods. In numberOfSectionsInTableView we change the return line to one, since we only have one section.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections
return 1;
}

In the tableView:numberOfRowsInSection we will return the number of items in our array.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section
return [self.tableData count];
}

In tableView:cellForRowAtIndexPath we will iterate through our numbers array and insert them in our TableView. Change this method in

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}

// Configure the cell
cell.textLabel.text = self.tableData[indexPath.row];

return cell;
}

Go back to the MainStoryboard and select the Table View. Select the Identity Inspector and change the Class to SearchViewController.

Select the Empty Prototype Cell in the TableView and select the Attributes Inspector. Change the Table View Cell Identifier to Cell

Build and Run, The Table View is filled with the numbers.

Next, go to the MainStoryboard and drag a search Bar and Search View Controller between the Navigation Controller and the TableView.

The Search View Controller enables the user to enter a search term and the results will be displayed in the TableView. First, go back to SearchViewController.m and enable our ViewController to be a delegate of UISearchDisplayDelegate

@interface SearchViewController () <UISearchDisplayDelegate>

Add a new property which will contain the results of our search term.

@property (nonatomic, strong) NSMutableArray *searchResults;

We will make our new Array the same size as our tableData array. Add the following line at the end of viewDidLoad.

self.searchResults = [NSMutableArray arrayWithCapacity:[self.tableData count]];

Next, we will implement our UISearchDisplayDelegate methods, in filterContentForSearchText we will handle the search filtering of our search term.

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
  [self.searchResults removeAllObjects];
  NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"SELF contains[c] %@", searchText];

  self.searchResults = [NSMutableArray arrayWithArray: [self.tableData filteredArrayUsingPredicate:resultPredicate]];
}

NSPredicate is an sort of expression that handles the search criteria. "c" means case-sensitive. The results are copied into our searchResults array. Next, implement the searchDisplayController:shouldReloadTableForSearchString method . When a user enters a search term this method is invoked.

-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
  [self filterContentForSearchText:searchString scope:[[self.searchDisplayController.searchBar scopeButtonTitles] objectAtIndex:[self.searchDisplayController.searchBar selectedScopeButtonIndex]]];

  return YES; 
}

We need to diplay the results of our search term in our tableView. Change the following methods.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
  // Return the number of rows in the section.
  if (tableView == self.searchDisplayController.searchResultsTableView)
  {
    return [self.searchResults count];
  } 
  else 
  { 
    return [self.tableData count];
  } 
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  static NSString *CellIdentifier = @"Cell";
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

  if (cell == nil)
  {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
  }

  if (tableView == self.searchDisplayController.searchResultsTableView)
  { 
    cell.textLabel.text = [self.searchResults objectAtIndex:indexPath.row];
  } 
  else 
  { 
    cell.textLabel.text = self.tableData[indexPath.row];
  }

  return cell;
}

Build and Run, enter a search string and the results will be dis played in the Search Controller Table View.

You can download the source code of the SearchTableViewDemo at the ioscreator repository on github.