UISearchController及NSPredicate谓词简单使用

前言


为了方便童鞋们更深刻的了解UISearchController的使用,写了这样一篇文章,来看看吧~~


概述


iOS8.0之前,搜索栏基本都是靠UISearchBar+UISearchDisplayController这对好基友来实现的。iOS8.0之后,苹果成全了它们,UISearchController便由此诞生。UISearchController的出现宣告着UISearchDisplayController的遗弃。

UISearchController不同于UISearchDisplayController的最大之处在于UISearchController继承自UIViewController,是一个实实在在的视图控制器,而UISearchDisplayController继承自NSObject,说白了是一个工具类。

常用属性及方法一览


UISearchController 常用属性

// 搜索界面的状态,只读属性。
@property (nonatomic, assign, getter = isActive) BOOL active;
// 决定在搜索时,底层的内容是否要变暗。
@property (nonatomic, assign) BOOL dimsBackgroundDuringPresentation; 
// 搜索栏使用的时候是否需要隐藏NavigationBar,默认值为true。
@property (nonatomic, assign) BOOL hidesNavigationBarDuringPresentation;  
// 自定义的搜索结果Controller
@property (nullable, nonatomic, strong, readonly) UIViewController *searchResultsController;
// 搜索栏,只读属性。
@property (nonatomic, strong, readonly) UISearchBar *searchBar;
// UISearchController的代理
@property (nullable, nonatomic, weak) id <UISearchControllerDelegate> delegate;
// UISearchResultsUpdating的代理
@property (nullable, nonatomic, weak) id <UISearchResultsUpdating> searchResultsUpdater;

UISearchBar 常用属性

// 控件的样式
@property(nonatomic)        UIBarStyle              barStyle;
// UISearchBarDelegate的代理
@property(nullable,nonatomic,weak) id<UISearchBarDelegate> delegate;
// 控件上的显示文字
@property(nullable,nonatomic,copy)   NSString               *text; 
// 控件上方的提示文字
@property(nullable,nonatomic,copy)   NSString               *prompt;  
// 控件的占位提示文字
@property(nullable,nonatomic,copy)   NSString               *placeholder;
// 控件是否透视效果
@property(nonatomic,assign,getter=isTranslucent) BOOL translucent

UISearchControllerDelegate 方法

方法由上到下的执行顺序

- (void)presentSearchController:(UISearchController *)searchController;
- (void)willPresentSearchController:(UISearchController *)searchController;
- (void)didPresentSearchController:(UISearchController *)searchController;
- (void)willDismissSearchController:(UISearchController *)searchController;
- (void)didDismissSearchController:(UISearchController *)searchController;

UISearchResultsUpdating 方法

// 更新搜索结果
- (void)updateSearchResultsForSearchController:(UISearchController *)searchController;

UISearchBarDelegate 常用方法

// 开始编辑
- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar;   
// 结束编辑
- (BOOL)searchBarShouldEndEditing:(UISearchBar *)searchBar; 
// 正在编辑
- (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text

与tableView的简单关联使用



上代码,先添加代理

@interface
<
UITableViewDelegate,
UITableViewDataSource,
UISearchResultsUpdating,
UISearchControllerDelegate,
UISearchBarDelegate
>
@end

将要跨方法使用的东东写成属性

@property (nonatomic, strong) UISearchController *searchController;
@property (nonatomic, strong) UITableView *tableView;
// 存数据的数组
@property (nonatomic, strong) NSMutableArray *dataArray;
// 搜索到的结果数组
@property (nonatomic, strong) NSMutableArray *searchArray;

具体方法实现



- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    [self createSearch];
    [self createTableView];
    [self createArray];
}
- (void)createTableView {
    self.tableView = [[UITableView alloc]initWithFrame:self.view.bounds style:UITableViewStylePlain];
    _tableView.delegate = self;
    _tableView.dataSource = self;
    [self.view addSubview:_tableView];
    _tableView.tableHeaderView = _searchController.searchBar;
    
    [_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:reusableIdentifier];
}
- (void)createArray {
    // 创建数据数组
    self.dataArray = [NSMutableArray array];
    // 给数据数组赋初值
    for (int i = 100; i <= 1000; i++) {
        [_dataArray addObject:[NSString stringWithFormat:@"%d",i]];
    }
    // 为了全面测试,数据数组增加英文与中文
    [_dataArray addObject:@"Small Tiger"];
    [_dataArray addObject:@"冠军"];
    // 创建结果数组
    self.searchArray = [NSMutableArray array];
}
- (void)createSearchController {
    self.searchController = [[UISearchController alloc]initWithSearchResultsController:nil];
    _searchController.searchResultsUpdater = self;
    _searchController.searchBar.frame = CGRectMake(_searchController.searchBar.frame.origin.x, _searchController.searchBar.frame.origin.y, _searchController.searchBar.frame.size.width, 44.0);
    _searchController.dimsBackgroundDuringPresentation = NO;
}

UITableView协议方法

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (_searchController.active) {
        return _searchArray.count;
    } else {
        return _dataArray.count;
    
    }
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reusableIdentifier];
    
    if (_searchController.active) {
        cell.textLabel.text = _searchArray[indexPath.row];
    } else {
         cell.textLabel.text = _dataArray[indexPath.row];
    
    }
    return cell;
    
}

UISearchResultsUpdating协议方法

- (void)updateSearchResultsForSearchController:(UISearchController *)searchController {
    NSString *searchString = self.searchController.searchBar.text;
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[c] %@",searchString];
    // 移除原数据
    if (_searchArray != nil) {
        [self.searchArray removeAllObjects];
    }
    // 过滤数据
    self.searchArray = [NSMutableArray arrayWithArray:[_dataArray filteredArrayUsingPredicate:predicate]];
    // 刷新表格
    [_tableView reloadData];
}

这样就简单实现了UISearchController与UITableView的关联使用

NSPredicate谓词


光有搜索框没什么卵用,还要有搜索功能,内部的功能就需要谓词来实现了

谓词的功能很强大,同时它还可以使用正则表达式,可以实现各种邮箱验证,手机号验证,以及各种查找功能。

基本常用的谓词:

  • 逻辑运算符 && AND || OR 都可以用
  • IN包含
  • 模糊查询
    • 以……开头 BEGINSWITH
    • 以……结尾 ENDSWITH
    • 包含….字符 CONTAINS
  • 用like进行模糊查询
    通配符:*表示任意个字符 ?表示单个字符
    like *a 以a结尾
    like a* 以a开头
    like *a* 包含a字符
    like ?a* 第二个字符为a的字符串

创建Book类

Book.h
@interface Book : NSObject
{
    NSInteger _price;
    NSString* _bookName;
}

- (instancetype)initWithPrice:(NSInteger)price andBookName:(NSString *)bookName;

@end



Book.m
#import "Book.h"

@implementation Book

- (instancetype)initWithPrice:(NSInteger)price andBookName:(NSString *)bookName {
    if (self = [super init]) {
        _price = price;
        _bookName = bookName;
    }
    return self;
}

- (NSString *)description {

    return [NSString stringWithFormat:@"Book price:%li,named %@",_price,_bookName];
}

@end


main.m
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        Book* book1 = [[Book alloc] initWithPrice:20 andBookName:@"C Programming"];
        Book* book2 = [[Book alloc] initWithPrice:32 andBookName:@"C++ Programming"];
        Book* book3 = [[Book alloc] initWithPrice:18 andBookName:@"Java Programming"];
        Book* book4 = [[Book alloc] initWithPrice:45 andBookName:@"OC guiding"];
        Book* book5 = [[Book alloc] initWithPrice:28 andBookName:@"iOS guiding"];
        NSArray* books = [NSArray arrayWithObjects:book1,book2,book3,book4,book5, nil];

        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"price > %i",30];
        NSArray *filterArray = [books filteredArrayUsingPredicate:predicate];
        NSLog(@"%@",filterArray);

//      逻辑运算符 和 IN
        predicate = [NSPredicate predicateWithFormat:@"bookName IN {'C Programming','C++ Programming'} AND price > 30"];
        filterArray = [books filteredArrayUsingPredicate:predicate];
        NSLog(@"%@",filterArray);

//      模糊查询 和 用通配符查询

        predicate = [NSPredicate predicateWithFormat:@"bookName CONTAINS 'guiding' || bookName like '*Program*' "]; //包含guiding或者包含Program
        filterArray = [books filteredArrayUsingPredicate:predicate];
        NSLog(@"%@",filterArray);



    }
    return 0;
}

心灵鸡汤


一青年途经某地,碰到一位老者,问:“这里如何?”老者反问:“你家乡如何?”青年答:“糟透了!我很讨厌。”老者说:“这里也一样糟。”后来又来了个青年问同样问题,老者也同样反问,青年回答说:“我家乡很好,我很想念。”老者便说:“这里也一样好。”旁听者觉得诧异,问老人家为何前后说法不一致呢?老者说:“你管得着吗?”

难受的时候摸摸自己的胸,告诉自己是个汉子,要坚强~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,042评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 89,996评论 2 384
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,674评论 0 345
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,340评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,404评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,749评论 1 289
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,902评论 3 405
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,662评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,110评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,451评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,577评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,258评论 4 328
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,848评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,726评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,952评论 1 264
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,271评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,452评论 2 348

推荐阅读更多精彩内容