One of my observations as a software developer is that there is a lack of essential coding examples. By essential, I literally mean a thing that is absolutely necessary or it's "essence".
es·sence
ˈesəns/
noun
Examples should not be overly complex. They exist to inform and educate. Many programming examples on the Internet are too complicated when they should be simple. I'll try my best to do this when possible.
So here is my first coding example for iOS in Objective C:
This example displays a list of fruit in a UITableView. When the user pulls down on the list, the search bar appears. When the user types in the search bar, the list is filtered to show only fruit names that match what they typed. If the user clears or cancels the search, the full list is then displayed. The results display inline in that they reuse the same UITableView.
In XCode, create a simple single view iOS application project. Add a UITableView instance to the view, change the class of the view controller to ViewController, and make connections from the controller's tableView outlet to the UITableView and connections from the UITableView's delegate and dataSource back to the view controller.
ViewController.h
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchControllerDelegate, UISearchBarDelegate, UISearchResultsUpdating>
@property (nonatomic, weak) IBOutlet UITableView * tableView;
@property (nonatomic, strong) UISearchController * searchController;
@property (nonatomic, strong) NSMutableArray * allItems;
@property (nonatomic, strong) NSMutableArray * filteredItems;
@property (nonatomic, weak) NSArray * displayedItems;
@end
ViewController.m
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
@synthesize tableView;
@synthesize searchController;
@synthesize allItems;
@synthesize displayedItems;
@synthesize filteredItems;
- (void)viewDidLoad {
[super viewDidLoad];
// Create a list of fruit to display in the table view.
self.allItems = [[NSMutableArray alloc] init];
[self.allItems addObject:@"Apples"];
[self.allItems addObject:@"Oranges"];
[self.allItems addObject:@"Pears"];
[self.allItems addObject:@"Grapes"];
[self.allItems addObject:@"Grapefruits"];
[self.allItems addObject:@"Lemons"];
[self.allItems addObject:@"Peaches"];
[self.allItems addObject:@"Pineapples"];
[self.allItems addObject:@"Cherries"];
[self.allItems addObject:@"Bananas"];
[self.allItems addObject:@"Watermelons"];
[self.allItems addObject:@"Cantaloupes"];
[self.allItems addObject:@"Limes"];
[self.allItems addObject:@"Strawberries"];
[self.allItems addObject:@"Blueberries"];
[self.allItems addObject:@"Raspberries"];
// Create a list to hold search results (filtered list)
self.filteredItems = [[NSMutableArray alloc] init];
// Initially display the full list. This variable will toggle between the full and the filtered lists.
self.displayedItems = self.allItems;
// Here's where we create our UISearchController
self.searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
self.searchController.searchResultsUpdater = self;
self.searchController.searchBar.delegate = self;
[self.searchController.searchBar sizeToFit];
// Add the UISearchBar to the top header of the table view
self.tableView.tableHeaderView = self.searchController.searchBar;
// Hides search bar initially. When the user pulls down on the list, the search bar is revealed.
[self.tableView setContentOffset:CGPointMake(0, self.searchController.searchBar.frame.size.height)];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)aTableView numberOfRowsInSection:(NSInteger)section {
return [self.displayedItems count];
}
- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)anIndexPath {
UITableViewCell * cell = [aTableView dequeueReusableCellWithIdentifier:@"FruitCell"];
if (cell == nil) {
cell = [[UITableViewCell alloc] init];
}
cell.textLabel.text = [self.displayedItems objectAtIndex:anIndexPath.row];
return cell;
}
// When the user types in the search bar, this method gets called.
- (void)updateSearchResultsForSearchController:(UISearchController *)aSearchController {
NSLog(@"updateSearchResultsForSearchController");
NSString *searchString = aSearchController.searchBar.text;
NSLog(@"searchString=%@", searchString);
// Check if the user cancelled or deleted the search term so we can display the full list instead.
if (![searchString isEqualToString:@""]) {
[self.filteredItems removeAllObjects];
for (NSString *str in self.allItems) {
if ([searchString isEqualToString:@""] || [str localizedCaseInsensitiveContainsString:searchString] == YES) {
NSLog(@"str=%@", str);
[self.filteredItems addObject:str];
}
}
self.displayedItems = self.filteredItems;
}
else {
self.displayedItems = self.allItems;
}
[self.tableView reloadData];
}
@end
I hope you found this fruitful. :-) Feel free to suggest improvements, ask questions or tell me I'm doing it all wrong!
See also:
UISearchController
https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UISearchController/index.html
Apple's TableSearch example
https://developer.apple.com/library/ios/samplecode/TableSearch_UISearchController/Introduction/Intro.html
Updating to the iOS 8 Search Controller
http://useyourloaf.com/blog/2015/02/16/updating-to-the-ios-8-search-controller.html



