UI:UISearchController 搜索

初始化方法

- (instancetype)initWithSearchResultsController:(nullable UIViewController *)searchResultsController;

常用屬性

  searchResultsUpdater:設置搜索結果刷新者(設置該屬性需遵守 UISearchResultsUpdating協議)
  active:設置(獲取)當前搜索狀態
  delegate:設置代理
  dimsBackgroundDuringPresentation:設置是否在搜索時顯示半透明背景
  hidesNavigationBarDuringPresentation:設置是否在搜索時隱藏導航欄
  searchResultsController:搜索結果控制器
  searchBar:搜索框

UISearchBar

  • 常用屬性

    autocapitalizationType:設置自動大小寫樣式
    tintColor:設置前景色
    barTintColor:設置背景顏色
    searchBarStyle:設置搜索框樣式
    translucent:設置是否半透明
    

UISearchResultsUpdating

  • UISearchResultsUpdating是一個結果刷新協議,其提供的方法如下
// 每次更新搜索框里的文字,就會調用這個方法
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController;

謂詞

  • NSPredicate 創建謂詞

    謂詞創建方法:
    +(NSPredicate *)predicateWithFormat:(NSString *)predicateFormat, ...;
    // 示例:創建一個以‘A’字母開頭的謂詞判斷
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF BEGINSWITH [CD] %@", @"A"];
    
  • 根據謂詞判斷在數組中進行搜索,得到結果數組的方法如下:

    - (NSArray<ObjectType> *)filteredArrayUsingPredicate:(NSPredicate *)predicate; 
    
  • 代碼示例:

#import "ViewController.h"

static NSString *const kReusableCellIdentifier = @"identifier";

@interface ViewController ()  <UITableViewDelegate, UITableViewDataSource, UISearchResultsUpdating>{

    NSMutableArray *_dataSource; /**< 數據源 */
    NSMutableArray *_searchResults; /**< 搜索結果 */
}

@property (nonatomic, strong) UITableView *tableView; /**< 表格視圖 */
@property (nonatomic, strong) UISearchController *searchController; /**< 搜索控制器 */

- (void)initializeDataSource; /**< 初始化數據源 */
- (void)initializeUserInterface; /**< 初始化用戶界面 */

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self initializeDataSource];
    [self initializeUserInterface];
}

#pragma mark *** Initialize methods ***

- (void)initializeDataSource {
    // 初始化數據源
    _dataSource = [NSMutableArray arrayWithArray:[UIFont familyNames]];
}

- (void)initializeUserInterface {

    self.view.backgroundColor = [UIColor whiteColor];

    // 關閉系統自動偏移
    self.automaticallyAdjustsScrollViewInsets = NO;

    // 加載表格視圖
    [self.view addSubview:self.tableView];

    // 添加導航欄
    self.tableView.tableHeaderView = self.searchController.searchBar;

}

#pragma mark *** <UITableViewDelegate, UITableViewDataSource> ***

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // 如果用戶正在搜索,則返回搜索結果的count,否則直接返回數據源數組的count;
    if (self.searchController.active) {
        return _searchResults.count;
    }else {
        return _dataSource.count;
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kReusableCellIdentifier];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kReusableCellIdentifier];
    }

    // 如果用戶正在搜索,則返回搜索結果對應的數據,否則直接返回數據數組對應的數據;
    if (self.searchController.active) {
        cell.textLabel.text = _searchResults[indexPath.row];
    }else {
        cell.textLabel.text = _dataSource[indexPath.row];
    }
    return cell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    // 取消選中
    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    if (self.searchController.active) {
        NSLog(@"%@", _searchResults[indexPath.row]);
    }else {
        NSLog(@"%@", _dataSource[indexPath.row]);
    }

    // 停止搜索
    self.searchController.active = NO;
}

#pragma mark *** <UISearchResultsUpdating> ***

// 每次更新搜索框里的文字,就會調用這個方法
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {

    // 獲取搜索框里地字符串
    NSString *searchString = searchController.searchBar.text;

    // 謂詞
    /**
     1.BEGINSWITH : 搜索結果的字符串是以搜索框里的字符開頭的
     2.ENDSWITH   : 搜索結果的字符串是以搜索框里的字符結尾的
     3.CONTAINS   : 搜索結果的字符串包含搜索框里的字符

    [c]不區分大小寫[d]不區分發音符號即沒有重音符號[cd]既不區分大小寫,也不區分發音符號。

     */

    // 創建謂詞
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF BEGINSWITH [CD] %@", searchString];

    // 如果搜索框里有文字,就按謂詞的匹配結果初始化結果數組,否則,就用字體列表數組初始化結果數組。
    if (_searchResults != nil && searchString.length > 0) {
        [_searchResults removeAllObjects];
        _searchResults = [NSMutableArray arrayWithArray:[_dataSource filteredArrayUsingPredicate:predicate]];
    } else if (searchString.length == 0) {
        _searchResults = [NSMutableArray arrayWithArray:_dataSource];
    }

    // 刷新表格視圖
    [_tableView reloadData];
}


#pragma mark *** Getters ***

- (UITableView *)tableView {
    if (!_tableView) {
        _tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 64, CGRectGetWidth(self.view.bounds), CGRectGetHeight(self.view.bounds) - 64) style:UITableViewStylePlain];
        // 設置代理
        _tableView.delegate = self;
        // 設置數據源
        _tableView.dataSource = self;
        // 設置單元格高度
        _tableView.rowHeight = 50;
    }
    return _tableView;
}


- (UISearchController *)searchController {
    if (!_searchController) {
        // 初始化搜索控制器
        _searchController = [[UISearchController alloc] initWithSearchResultsController:nil];
        // 設置代理
        _searchController.searchResultsUpdater = self;
        // 設置半透明背景,當設置當前視圖控制器作為搜索結果的視圖控制器時,要設為NO;
        _searchController.dimsBackgroundDuringPresentation = NO;
        // 隱藏導航欄
        _searchController.hidesNavigationBarDuringPresentation = YES;
        // 關掉自動大寫鎖定
        _searchController.searchBar.autocapitalizationType = UITextAutocapitalizationTypeNone;
        // 設置searchBar的frame
        _searchController.searchBar.frame = CGRectMake(0, 0, CGRectGetWidth(self.view.bounds), 44);
    }
    return _searchController;
}

@end
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 轉載自:http://www.cocoachina.com/ios/20160111/14926.html 1、大...
    一筆春秋閱讀 2,871評論 0 2
  • NSPredicate是一個Foundation類,它指定數據被獲取或者過濾的方式。它的查詢語言就像SQL的WHE...
    Dean麥兜閱讀 382評論 0 2
  • 廢話不多說,直接上干貨 ---------------------------------------------...
    小小趙紙農閱讀 3,441評論 0 15
  • 前言 有時我們需要在一大段長文本中過濾出我們需要的字段,或者檢驗該文本是否符合要求(該文本是否是郵箱,鏈接,電話號...
    進無盡閱讀 993評論 0 1
  • 長笑踏歌行,寒霜溯發纓。 青虹光映雪,玉樹寞留旌。 易水風蕭恨,蛟宮蟒野驚。 嵇琴書仗義,美酒壯豪情。 關前擒禍首...
    周延龍閱讀 180評論 2 2