之前我寫過一篇關於在tableView中利用謂詞搜索的隨筆,當時使用的是自定義textField,最近在寫電子書,需要在書目時實現搜索功能.所以在此把以前用於實現搜索功能系統提供的的SearchBar和SearchDisplayController的方法在這裡和大家分享一下.不過在iOS8滯後,蘋果已經不再推薦我們是使用這兩個舊東西,而是讓我們使用UISearchController,自然我也會把這個新東西的用法在這裡演示一下.
SearchBar和SearchDisplayController
先在視圖xib文件中添加tableView,在表上面添加SearchBar和SearchDisplayController.如圖:

需要用到的協議有:<UITableViewDataSource,UITableViewDelegate,UISearchBarDelegate,UISearchDisplayDelegate>
我在這裡聲明了兩個數據,用來保存搜索數據和搜索結果:
@property(nonatomic,retain)NSMutableArray *dataArray;
@property(nonatomic,retain)NSMutableArray *resultArray;
初始化數組:
self.dataArray=[[NSMutableArray alloc]initWithObjects:@"張三",@"李四",@"王五",@"阿五",@"雲飛",@"asd", nil];
在這裡其實有兩個表,一個是搜索前的所有數據,另一個是展示搜索結果,所以在寫tabbleView的協議時需要進行區分:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView==self.tableView) {
return self.dataArray.count;
}
else
{
return self.resultArray.count;
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *str=@"cell";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:str];
if (cell==nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:str];
}
if (tableView==self.tableView) {
cell.textLabel.text=self.dataArray[indexPath.row];
}
else
{
cell.textLabel.text=self.resultArray[indexPath.row];
}
return cell;
}
接著是UISearchBarDelegate,UISearchDisplayDelegate的協議方法
-(BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
NSLog(@"搜索開始");
return YES;
}
-(BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar
{
NSLog(@"搜索結束");
return YES;
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
NSPredicate *preicate=[NSPredicate predicateWithFormat:@"SELF CONTAINS[c] %@",searchString];
if (self.resultArray!=nil) {
[self.resultArray removeAllObjects];
}
self.resultArray=[NSMutableArray arrayWithArray:[self.dataArray filteredArrayUsingPredicate:preicate]];
NSLog(@"%lu",(unsigned long)self.resultArray.count);
return YES;
}
在這裡我們用來區分的關鍵代碼還是謂詞,相對於正則表達式,謂詞已經是很簡單了.不過我還是記不住
運行結果如下:


雖然這個很好用,但是蘋果公司在iOS8的時候已經講他打上了紅槓,推薦我們使用的是UISearchController
首先需要添加的協議有<UITableViewDataSource,UITableViewDelegate,UISearchBarDelegate,UISearchResultsUpdating>
還是現在xib文件中拖入一個tabView,為了不相互影響,我將兩個放在不同的視圖裡
同樣聲明兩個數組,功能同上;還有一個UIsearchController(因為我不知道拖的話是哪個控件,所以只好手寫):
@property(nonatomic,retain)UISearchController *seachController;
@property(nonatomic,retain)NSMutableArray *resultArray;
@property(nonatomic,retain)NSMutableArray *dataArray;
初始化數組並手動創建searchController:
self.dataArray=[[NSMutableArray alloc]initWithObjects:@"張三",@"李四",@"王五",@"阿五",@"雲飛",@"asd", nil];
self.seachController=[[UISearchController alloc]initWithSearchResultsController:nil];
self.seachController.searchResultsUpdater=self;
self.seachController.dimsBackgroundDuringPresentation=NO;
self.seachController.hidesNavigationBarDuringPresentation=NO;
self.seachController.searchBar.frame=CGRectMake(self.seachController.searchBar.frame.origin.x, self.seachController.searchBar.frame.origin.y, self.seachController.searchBar.frame.size.width, 44.0);
self.tableView.tableHeaderView=self.seachController.searchBar;
同樣道理,這裡也是有兩個搜索結果,所以需要判斷:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (!self.seachController.active) {
return self.dataArray.count;
}
else
{
return self.resultArray.count;
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *str=@"cell";
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:str];
if (cell==nil) {
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:str];
}
if (!self.seachController.active) {
cell.textLabel.text=self.dataArray[indexPath.row];
}
else
{
cell.textLabel.text=self.resultArray[indexPath.row];
}
return cell;
}
協議方法,在這裡我們用的還是謂詞判斷
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController
{
NSString *searchString=self.seachController.searchBar.text;
NSPredicate *preicate=[NSPredicate predicateWithFormat:@"SELF CONTAINS[c] %@",searchString];
if (self.resultArray!=nil) {
[self.resultArray removeAllObjects];
}
self.resultArray=[NSMutableArray arrayWithArray:[self.dataArray filteredArrayUsingPredicate:preicate]];
NSLog(@"%lu",(unsigned long)self.resultArray.count);
[self.tableView reloadData];
}
結果演示:

