UITableView的搜尋:SearchBar和SearchDisplayController;UISearchController,
之前我寫過一篇關於在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;}
在這裡我們用來區分的關鍵代碼還是謂詞,相對於Regex,謂詞已經是很簡單了.不過我還是記不住
運行結果如下:
雖然這個很好用,但是蘋果公司在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];}
結果示範:
我寫的隨筆大部分是有源碼的,如果有想要的,可以聯絡我.我的設定檔裡有我的QQ.