iOS - UISearchController搜索框与NSPredicate谓词
2016-04-18 14:19
507 查看
一、UISearchController
搜索框的用处很大,就不用废话了,在iOS8以前是用UISearchBar加代理实现的。现在已经废弃,鼓励使用新的UISearchController
首先遵守UISearchResultsUpdating协议
@interface RootTableViewController ()<UISearchResultsUpdating> //再实现必须的方法 -(void)updateSearchResultsForSearchController:(UISearchController *)searchController //搜索代理方法,搜索框获得第一响应或内容变化时触发 -(void)updateSearchResultsForSearchController:(UISearchController *)searchController { NSLog(@激活了搜索框"); }
再创建UISearchController,因为很多方法都要对搜索框进行判断,写成一个属性
@property (nonatomic,retain)UISearchController *searchC; //初始化UISearchController,把搜索框添加在tableView的headerView上 //添加搜索栏 _searchC = [[UISearchController alloc]initWithSearchResultsController:nil]; //设置frame _searchC.searchBar.frame = CGRectMake(0, 0, 414, 50); //更新代理 _searchC.searchResultsUpdater = self; //搜索结果不变灰 _searchC.dimsBackgroundDuringPresentation = NO; //添加到header self.tableView.tableHeaderView = _searchC.searchBar;
这样运行就能看到搜索框了,点击也会打印文字。
二、NSPredicate谓词
光有搜索框没什么卵用,还要有搜索功能,内部的功能就需要谓词来实现了谓词的功能很强大,同时它还可以使用正则表达式,可以实现各种邮箱验证,手机号验证,以及各种查找功能。
使用的方法
1.创建谓词
NSPredicate *testPredicate = [NSPredicate predicateWithFormat:@"age < 50"];
谓词的语法也很全面:
Format后面可以跟很多:
(1)比较运算符>,<,==,>=,<=,!=可用于数值及字符串例:@"number > 100"
(2)范围运算符:IN、BETWEEN例:@"number BETWEEN {1,5}" @"address IN {'shanghai','beijing'}"
(3)字符串本身:SELF 例:@“SELF == ‘APPLE’"
(4)字符串相关:
BEGINSWITH、ENDSWITH、CONTAINS例:@"name CONTAIN[cd] 'ang'" //包含某个字符串
@"name BEGINSWITH[c] 'sh'" //以某个字符串开头
@"name ENDSWITH[d] 'ang'" //以某个字符串结束
注:[c]不区分大小写[d]不区分发音符号即没有重音符号[cd]既不区分大小写,也不区分发音符号。
(5)通配符:LIKE例:@"name LIKE[cd] 'er'" //代表通配符,Like也接受[cd]. @"name LIKE[cd] '???er'"
(6)正则表达式:MATCHES例:NSString *regex = @"^A.+e$"; //以A开头,e结尾 @"name MATCHES %@",regex
用正则表达式简单匹配一个邮箱
/* 正则表达式常用的 ^ --- 匹配输入字符串的开始位置 $ --- 匹配输入字符串的结束位置 * --- 匹配前面的子表达式任意次 + --- 匹配前面的子表达式一次或多次 ? --- 匹配前面的子表达式零次或一次 .点 --- 匹配除“\r\n”之外的任何单个字符 \d --- 匹配一个数字字符。等价于[0-9] \D --- 匹配一个非数字字符。等价于[^0-9]。 \w --- 等价于[A-Za-z_0-9]。 \转义 */ //匹配一个邮箱地址 //结构 (字母数字)@(字母数字)(.)(字母2~4个) NSString *emailRegex = @"\\w+@\\w+\\.[A-Za-z]{2,4}"; NSPredicate *emailPredicate = [NSPredicate predicateWithFormat:@"name MATCHES %@",emailRegex];
2.进行过滤,有两种方法,
一种是对数组进行过滤,把符合谓词条件的对象产生一个新的数组
一种是单独判断一个对象是否满足谓词条件,返回值为BOOL
//过滤产生新的数组 self.searchArray = [NSMutableArray arrayWithArray:[_dataArray filteredArrayUsingPredicate:testPredicate]]; //对单个对象依次判断 if ([testPredicate evaluateWithObject:personDic]) { //添加到搜索数组当中去 [_searchArray addObject:personDic]; }
这里要注意一点,数组内放的对象可以是一个字典,也可以是一个类。
最后给出我写的完整的tableView上搜索框的使用
// RootTableViewController.m #import "RootTableViewController.h" #import "Person.h" @interface RootTableViewController ()<UISearchResultsUpdating> @property (nonatomic,retain)NSMutableArray *dataArray;//全部数据数组 @property (nonatomic,retain)NSMutableArray *searchArray;//搜索结果数组 @property (nonatomic,retain)UISearchController *searchC;//搜索框 @end @implementation RootTableViewController //懒加载 -(NSMutableArray *)dataArray { if (!_dataArray) { _dataArray = [[NSMutableArray alloc]init]; } return _dataArray; } -(NSMutableArray *)searchArray { if (!_searchArray) { _searchArray = [[NSMutableArray alloc]init]; } return _searchArray; } - (void)viewDidLoad { [super viewDidLoad]; self.navigationItem.title = @"search"; //添加搜索栏 _searchC = [[UISearchController alloc]initWithSearchResultsController:nil]; _searchC.searchBar.frame = CGRectMake(0, 0, 414, 50); //更新代理 _searchC.searchResultsUpdater = self; //搜索结果不变灰 _searchC.dimsBackgroundDuringPresentation = NO; //便利初始化创建数据 NSArray *nameArray = [NSArray arrayWithObjects:@"王",@"李型剂",@"王青云",@"张菲菲",@"abe",@"ABe",@"aBS",@"wang@12.com", @"wan@126.cn",nil]; int ageList[] = {12,43,56,123,34,44,21,22,11}; for (int i = 0; i < 9; i++) { Person *person = [Person personWithName:nameArray[i] Age:(NSInteger)ageList[i]]; //把全部人存到数组当中去 [self.dataArray addObject:person]; } //添加到header self.tableView.tableHeaderView = _searchC.searchBar; //注册单元格 [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"CELL"]; } //搜索代理方法,搜索框获得第一响应或内容变化时触发 -(void)updateSearchResultsForSearchController:(UISearchController *)searchController { //得到搜索框的文字 NSString* str = searchController.searchBar.text; NSLog(@"%@",str); //创建个谓词 // < > >= <= != NSPredicate *testPredicate = [NSPredicate predicateWithFormat:@"age < 50"]; //IN BETWEEN NSPredicate *testPredicate_2 = [NSPredicate predicateWithFormat:@"age BETWEEN {50,100}"]; NSPredicate *testPredicate_3 = [NSPredicate predicateWithFormat:@"name IN{'王','张菲菲'}"]; //testPredicate // @"name CONTAINS[cd] 'ang'" //包含某个字符串 // @"name BEGINSWITH[c] 'sh'" //以某个字符串开头 // @"name ENDSWITH[d] 'ang'" //以某个字符串结束 NSPredicate *namePredicate = [NSPredicate predicateWithFormat:@"name CONTAINS %@",str]; //[c]不区分大小写 [d]无音调 [cd]两个都不要 NSPredicate *namePredicate_2 = [NSPredicate predicateWithFormat:@"name CONTAINS[c] %@ ",str]; //正则表达式 //匹配一个邮箱地址 //结构 (字母数字)@(字母数字)(.)(字母2~4个) NSString *emailRegex = @"\\w+@\\w+\\.[A-Za-z]{2,4}"; NSPredicate *emailPredicate = [NSPredicate predicateWithFormat:@"name MATCHES %@",emailRegex]; //清空搜索数组 [_searchArray removeAllObjects]; //过滤,这里可以换不同的谓词进行试验 self.searchArray = [NSMutableArray arrayWithArray:[_dataArray filteredArrayUsingPredicate:namePredicate_2]]; for (Person *person in _searchArray) { NSLog(@"%@,%ld",person.name,person.age); } //刷新tableView [self.tableView reloadData]; } #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { #warning Incomplete implementation, return the number of sections return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { #warning Incomplete implementation, return the number of rows //如果搜索框激活 if (_searchC.active) { return _searchArray.count; } return _dataArray.count; } //cell的填充 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CELL" forIndexPath:indexPath]; Person *onePerson = _dataArray[indexPath.row]; //如果搜索框激活 if (_searchC.active) { onePerson = _searchArray[indexPath.row]; } cell.textLabel.text = [NSString stringWithFormat:@"姓名: %@, ----- 年龄: %ld",onePerson.name,onePerson.age]; return cell; } @end
person类
Person.h
#import <Foundation/Foundation.h> @interface Person : NSObject @property (nonatomic,retain)NSString *name;//姓名 @property (nonatomic,assign)NSInteger age;//年龄 //init -(instancetype)initWithName:(NSString*)name Age:(NSInteger)age; //便利 +(instancetype)personWithName:(NSString*)name Age:(NSInteger)age; @end
Person.m
#import "Person.h" @implementation Person //重写初始化方法 -(instancetype)initWithName:(NSString *)name Age:(NSInteger)age { self = [super init]; if (self) { _age = age; _name = name; } return self; } //便利构造器 +(instancetype)personWithName:(NSString *)name Age:(NSInteger)age { Person *person = [[Person alloc]initWithName:name Age:age]; return person; } @end
文/简单也好(简书作者)
原文链接:http://www.jianshu.com/p/95e9c8660198
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
相关文章推荐
- identityHashCode, WeakReference,ReferenceQueue和Lucene WeakIdentityMap
- UITableView的常用代理方法
- AVI Player with Playmaker actions 使用UGUI显示视频以及控制播放视频 (二)
- 理解 Android Build 系统
- AndroidUI--SlidingMenu使用例子
- IOS-UITableView入门(2)
- 背水一战 Windows 10 (7) - 控件 UI: VisualState, VisualStateManager, 控件的默认 UI
- 原生的强大DOM选择器querySelector
- String、StringBuffer和StringBuilder的区别
- 南京理工大学第八届程序设计大赛(校外镜像) F sequence
- APUE阅读笔记(八)——进程控制
- 南京理工大学第八届程序设计大赛(校外镜像) - sequence (贪心)
- Druid基本使用配置以及如何查看sql信息监控日志
- IOS开发之001 控件类 UIlabel全解
- IOS开发之小实例--使用UIImagePickerController创建一个简单的相机应用程序
- 【Arduino官方教程第一辑】示例程序 1-5 LED亮度渐隐
- Android Stuidio解决更新下载时无法连接URL的问题
- Your Podfile has had smart quotes sanitised. To avoid issues in the future, you should not use TextE
- Easyui datagrid editor为combobox时指定数据源
- querySelector 和 querySelectorAll 的使用