Add a Search Bar to a Table View in iOS 7

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 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 iOS7SearchBarTableViewTutorial 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. 

Go to the Storyboard and drag a Table View on top of the main view, resize the view so the status bar is still visible. The Storyboard should look like this.

Next, go the the ViewController.m file and add the following property in the @interface section.

@interface SearchViewController ()

@property (nonatomic, strong) NSArray *tableData;

@end

In viewDidLoad we fill the array with numbers.

- (void)viewDidLoad
{
[super viewDidLoad];

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

Add the tableView:numberOfRowsInSection method

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

The number of rows is equal to the number of items in our array, in this case three. Add the tableView:cellForRowAtIndexPath method

- (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;
}

The method will iterate through our tableData array and insert them in our Table View. When we should Build and Run the project now, the Table View is still empty, because we haven't connected our datasource and delegate outlets yet. Go to the Storyboard. Ctrl and drag from the Table View to the View Controller icon and select the dataSource outlet. Repeat this for the delegate outlet.

Now the connection has been made, Build and Run the project, you should see the rows containing the items of our array.

Go to the Storyboard and drag a Search Bar and Search Display Controller between the status bar and the Table View.

The Search Bar enables the user to enter a search term and the Search Display Controller will display the results in the Table View. Go back ViewController.m and enable our ViewController to be a delegate of UISearchDisplayDelegate

@interface ViewController () <UISearchDisplayDelegate>

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

@property (nonatomic, strong) NSMutableArray *searchResult;

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

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

Next, we will implement our UISearchDisplayDelegate methods, add the filterContentForSearchText method

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

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

In this method we will handle the search filtering of our search term. 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.

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

return YES;
}

When a user enters a search term this method is invoked. It reloads our table with the correct search results. We need to display the results of our search term in our tableView. Change the following methods.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView)
{
return [self.searchResult 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.searchResult objectAtIndex:indexPath.row];
}
else
{
cell.textLabel.text = self.tableData[indexPath.row];
}

return cell;
}

The if else statement decides which data should be displayed. Build and Run the project, enter a search term and the results will be displayed.

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