之前我寫過一篇關於在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]; }
結果演示: