在iOS8之前搜索框是做爲一個控件添加到TableViewController中,
有系統自帶的搜索變量self.searchDisplayController
遵照一個搜索顯示的協議<UISearchDisplayDelegate>,實現方法就能夠了。
在ProductTableViewController.m文件中
#import "ProductTableViewController.h"
#import "Product.h"
@interface ProductTableViewController ()<UISearchDisplayDelegate>
@property(nonatomic,strong)NSArray *allProducts;
//用於存儲搜索結果的數組
@property(nonatomic,strong)NSMutableArray *resultProducts;
@end
@implementation ProductTableViewController
- (NSArray *)allProducts{
if(!_allProducts){
_allProducts = [Product demoData];
}
return _allProducts;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.resultProducts = [NSMutableArray array];
// 爲用於展現搜索結果的表格註冊單元格
[self.searchDisplayController.searchResultsTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell"];
}
#pragma mark - Table view data source
//實現tableView的三問
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(tableView==self.searchDisplayController.searchResultsTableView){
return self.resultProducts.count;
}else{
return self.allProducts.count;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
Product *p = nil;
if(tableView==self.tableView){
p = self.allProducts[indexPath.row];
}else{
p = self.resultProducts[indexPath.row];
}
cell.textLabel.text = p.name;
return cell;
}
實現協議:
//只要在搜索框中修改搜索的內容,當即調用此方法,參數searchString就是用戶此時在搜索框中輸入的文本
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString{
NSMutableArray *tempArray = [NSMutableArray array];
//獲取此時在searchBar的scope中哪一個按鈕被選中
NSInteger selectedScope = self.searchDisplayController.searchBar.selectedScopeButtonIndex;
for (Product *p in self.allProducts) {
//判斷輸入的searchString是否在p的name中出現了,NSRange包含兩部分,一個是location,一個是length,location記錄的時在name中包含searchString的位置,length記錄佔用的長度;經過判斷range中得length,若是長度爲0 則表明name不包含search。
NSRange range = [p.name rangeOfString:searchString];
if(range.length>0 && p.type==selectedScope){
[tempArray addObject:p];
}
}
self.resultProducts = tempArray;
return YES;
}
//選定的scope中的按鈕發生改變時,執行該方法,參數searchOption表明的就是當前被選中的scope
//按鈕的索引
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchScope:(NSInteger)searchOption{
NSMutableArray *tempArray = [NSMutableArray array];
//獲取此時在searchBar中輸入的文本
NSString *text = self.searchDisplayController.searchBar.text;
for (Product *p in self.allProducts) {
//判斷輸入的searchString是否在p的name中出現了,NSRange包含兩部分,一個是location,一個是length,location記錄的時在name中包含searchString的位置,length記錄佔用的長度,經過判斷range中得length,若是長度爲0 則表明name不包含search
NSRange range = [p.name rangeOfString:text];
if(range.length>0 && p.type==searchOption){
[tempArray addObject:p];
}
}
self.resultProducts = tempArray;
return YES;
}
在iOS8中,搜索框,是做爲一個組成部分,聚合方式
搜索框結構圖:
在MainTableViewController.m文件中
#import "MainTableViewController.h"
#import "Product.h"
#import "SearchResultTableViewController.h"
//用於顯示沒有搜索動做之前的所有數據的表視圖控制器
@interface MainTableViewController ()<UISearchResultsUpdating,UISearchBarDelegate>
@property(nonatomic,strong)NSArray *allProducts;
//用於控制全部結果顯示的控制器
@property(nonatomic,strong)UISearchController *searchController;
//用於展現搜索結果的控制器,是自定義的用於展現結果的那個控制器
@property(nonatomic,strong)SearchResultTableViewController *showResultViewController;
@end
@implementation MainTableViewController
- (NSArray *)allProducts{
if(!_allProducts){
_allProducts = [Product demoData];
}
return _allProducts;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.showResultViewController = [[SearchResultTableViewController alloc]init];
self.searchController = [[UISearchController alloc]initWithSearchResultsController:self.showResultViewController];
//設置搜索控制器的結果更新時由誰代理
self.searchController.searchResultsUpdater = self;
//設置顯示的搜索bar的大小和樣式
[self.searchController.searchBar sizeToFit];
self.searchController.searchBar.scopeButtonTitles=@[@"設備",@"軟件",@"其餘"];
//將搜索bar添加到表頭視圖中
self.tableView.tableHeaderView = self.searchController.searchBar;
//設置是否在數據發現變動時,容許切換控制器
self.definesPresentationContext = YES;
//爲了獲取scope按鈕被改變這個時機,須要設置搜索框的代理
//searchBar中包含一個文本框和一個分段控件
self.searchController.searchBar.delegate = self;
}
#pragma mark - 主TableViewController的tableView內容設置,回答三問
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.allProducts.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
Product *p = self.allProducts[indexPath.row];
cell.textLabel.text = p.name;
return cell;
}
#pragma mark - UISearchResultsUpdating
//實現協議中的方法:更新搜索內容
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController{
//用戶輸入的搜索文本
NSString *text = searchController.searchBar.text;
//用戶選擇的scope按鈕
NSInteger selectedIndex = searchController.searchBar.selectedScopeButtonIndex;
NSMutableArray *temp = [NSMutableArray array];
for (Product *p in self.allProducts) {
NSRange range = [p.name rangeOfString:text];
if(range.length>0 && p.type==selectedIndex){
[temp addObject:p];
}
}
//將搜索結果傳給用於展現結果的那個控制器
self.showResultViewController.resultArray = [temp copy];
[self.showResultViewController.tableView reloadData];
}
#pragma mark - UISearchBarDelegate
- (void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:(NSInteger)selectedScope{
[self updateSearchResultsForSearchController:self.searchController];
}
@end
在SearchResultTableViewController.m文件中
#import "SearchResultTableViewController.h"
#import "Product.h"
@interface SearchResultTableViewController ()
@end
@implementation SearchResultTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cell2"];
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.resultArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell2" forIndexPath:indexPath];
Product *p = self.resultArray[indexPath.row];
cell.textLabel.text = p.name;
return cell;
}
@end