Easy Things: UITableView Search Bars
This is very easy to do with storyboards with ONE key detail to remember1. But I struggled for a bit. Most of the examples that I saw did not highlight the key detail.
Basic idea of how it works:
The search bar controller has a separate tableview that it populates with the results of your search.
It populates its tableview with the same methods, though.
So you create a separate datasource that is filled with the results of your search, and fill the tableview accordingly.
But first, Here is the simplest way:
In your Storyboard, drag searchBar And Controller onto your tableview. You get all the delegate setup for free.
add <UISearch1. create an NSArray property to hold the objects from the search results.
you need to make four simple changes to your code
The first, and least obvious to me. in your cellForRowAtIndexPath method, you need to change UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; to UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
return the row count - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return (tableView == self.searchDisplayController.searchResultsTableView)?self.searchObjects.count:self.objects.count; }
After dequeuing Cell as shown above, set the Cell's content with the correct data source. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { ... cell.textLabel.text = (tableView == self.searchDisplayController.searchResultsTableView)?self.searchObjects[indexPath.row]:self.objects[indexPath.row]; return cell; }
Use the searchDisplayController delegate method to return the revised datasource according to whatever predicate you would like to use: -(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString { NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"description contains[c] %@", searchString]; self.searchObjects = [[NSArray arrayWithArray:self.objects] filteredArrayUsingPredicate:resultPredicate]; return YES; } NOTE" "description" should be replaced with whatever property of the object that fills the array or datasource of your tableView. (another good reason to fill in the description property of your custom objects...
NOT NECESSARY, but nice is to add <UISearchBarDelegate, UISearchDisplayDelegate> to the interface declarations. It gives you method completion for free if you are using any of the delegate methods.
That's it. If using storyboards, then you don't even need to declare the searchDisplayControllerDelegate protocol up top as storyboard takes care of that for you.
Spoiler alert -- use [self.tableView..., not [tableView...: UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; ↩︎








