1. 程式人生 > >iOS搜尋框的實現

iOS搜尋框的實現

搜尋框是我們在實際開發中比較常用到的控制元件之一,可以說幾乎每一個應用程式中都會使用到搜尋框,例如QQ、微信等都用到了搜尋框

這裡寫圖片描述

這裡寫圖片描述

iOS中的搜尋框實現起來相對簡單一點,實現方法大致有iOS8.0之前的利用UISearchBar和UIDisplayController實現,這種方法實現效果是沒有問題的,但是會報警告,意思是iOS8.0之後不推薦使用這種方法,也就是不推薦使用UISearchDisplayDelegate ,但是可以通過 UISearchController 實現 UISearchResultsUpdating 這個委託同樣可以實現上面的效果。在這裡呢,我們只討論後一種方法。

一、實現步驟

1. 遵守代理協議

/*
這裡我們主要用到了UISearchResultsUpdating這個協議的-(void)updateSearchResultsForSearchController:(UISearchController *)searchController方法。作用是當搜尋框的內容或操作發生變化、操作框成為第一相應者時呼叫此方法,這是我們實現搜尋操作的主要方法。
*/
@interface ViewController ()<UITableViewDelegate,UITableViewDataSource,UISearchBarDelegate,UISearchResultsUpdating
>
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

2. 宣告屬性

//搜尋控制器
@property (nonatomic, strong) UISearchController *searchController;
//存放tableView中顯示資料的陣列
@property (strong,nonatomic) NSMutableArray  *dataList;
//存放搜尋列表中顯示資料的陣列
@property (strong,nonatomic) NSMutableArray  *searchList;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3. 初始化屬性

- (void)viewDidLoad {
    [super viewDidLoad];
//初始化陣列並賦值 self.dataList=[NSMutableArray arrayWithCapacity:100]; for (NSInteger i=0; i<100; i++) { [self.dataList addObject:[NSString stringWithFormat:@"%ld-FlyElephant",(long)i]]; } //初始化UISearchController併為其設定屬性 _searchController = [[UISearchController alloc] initWithSearchResultsController:nil]; //設定代理物件 _searchController.searchResultsUpdater = self; //設定搜尋時,背景變暗色 _searchController.dimsBackgroundDuringPresentation = NO; //設定搜尋時,背景變模糊 _searchController.obscuresBackgroundDuringPresentation = NO; //隱藏導航欄 _searchController.hidesNavigationBarDuringPresentation = NO; //設定搜尋框的frame _searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, self.searchController.searchBar.frame.origin.y, self.searchController.searchBar.frame.size.width, 44.0); //將搜尋框設定為tableView的組頭 self.tableView.tableHeaderView = self.searchController.searchBar; }

4. 返回行數

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    //如果searchController被啟用就返回搜尋陣列的行數,否則返回資料陣列的行數
    if (self.searchController.active) {
        return [self.searchList count];
    }else{
        return [self.dataList count];
    }
}

6. 執行過濾操作

-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
    //獲取搜尋框中使用者輸入的字串
    NSString *searchString = [self.searchController.searchBar text];
    //指定過濾條件,SELF表示要查詢集合中物件,contain[c]表示包含字串,%@是字串內容
    NSPredicate *preicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[c] %@", searchString];
    //如果搜尋陣列中存在物件,即上次搜尋的結果,則清除這些物件
    if (self.searchList!= nil) {
        [self.searchList removeAllObjects];
    }
    //通過過濾條件過濾資料
    self.searchList= [NSMutableArray arrayWithArray:[_dataList filteredArrayUsingPredicate:preicate]];
    //重新整理表格
    [self.tableView reloadData];
}
二、實現效果

這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

-- - - - - - --  -- -  - -- - - -- - -

UISearchController的cancel按鈕自定義中文取消 有兩種方法

一:遍歷法

  1. - (void)updateSearchResultsForSearchController:(UISearchController *)searchController {  
  2.     //    //修改"Cancle"退出字眼,這樣修改,按鈕一開始就直接出現,而不是搜尋的時候再出現
  3.     searchController.searchBar.showsCancelButton = YES;  
  4.     for(id sousuo in [searchController.searchBar subviews]) {  
  5.         for (id view in [sousuo subviews]) {  
  6.             if([view isKindOfClass:[UIButton class]]){  
  7.                 UIButton *btn = (UIButton *)view;  
  8.                 [btn setTitle:@"取消" forState:UIControlStateNormal];  
  9.                 [btn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];  
  10.             }  
  11.         }  
  12.     }  
  13. }  

二:真機環境下,修改plist檔案的語言環境,最為方便的方法

  1. // 改變取消按鈕字型顏色
  2.     self.searchController.searchBar.tintColor =  [UIColor whiteColor];  
  3.     // 改變searchBar背景顏色
  4.     self.searchController.searchBar.barTintColor =  [UIColor whiteColor];  
  5.     // 取消searchBar上下邊緣的分割線
  6.     self.searchController.searchBar.backgroundImage = [[UIImage alloc] init];  


有時候彈出的搜尋VC的搜尋框會先彈出螢幕外一下,然後又彈回來,可以試試這一句程式碼

  1. self.definesPresentationContext = YES;