iOS学习之NSPredictae及搜索框的实现
NSPredicate
Predicate 即谓词逻辑, Cocoa框架中的NSPredicate用于查询,作用是从数据堆中根据条件进行筛选。计算谓词之后返回的结果永远为BOOL类型的值,当程序使用谓词对集合元素进行过滤时,程序会自动遍历其元素,并根据集合元素来计算谓词的值,当这个集合中的元素计算谓词并返回YES时,这个元素才会被保留下来。
最常用的函数:
+ (NSPredicate *)predicateWithFormat:(NSString *)predicateFormat, ...;
比较运算符 > 、< 、== 、 >= 、<= 、 !=
例:NSNumber *testNumber = @123;
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF = 123"];
if ([predicate evaluateWithObject:testNumber]) {
NSLog(@"testString:%@", testNumber);
- 范围运算符:IN 、BETWEEN
BETWEEN {下限,上限}的格式,要求该表达式必须大于或等于下限,并小于或等于上限(两者之间)
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF BETWEEN {100, 200}"];
- 字符串本身:SELF
例:@"SELF == 'APPLE'"
- 字符串相关:BEGINSWITH、ENDSWITH、CONTAINS
- BEGINSWITH:检查某个字符串是否以指定的字符串开头
- ENDSWITH:检查某个字符串是否以指定的字符串结尾
- CONTAINS:检查某个字符串是否包含指定的字符串
- LIKE:检查某个字符串是否匹配指定的字符串模板。Like也接受[cd]//?代表一个字符和*代表任意多个字符两个通配符[cd;
例:@"name CONTAIN[cd] 'ang'" //包含某个字符串
@"name BEGINSWITH[c] 'sh'" //以sh字符串开头
@"name ENDSWITH[d] 'ang'" //以ang字符串结束、
@"name LIKE[cd] '*er*'" //*代表通配符, name的值中包含er则返回YES
@"name LIKE[cd] '???er*'" //表示name的第4、5个字符为er时返回YES
注:[c]不区分大小写 , [d]不区分发音符号即没有重音符号 , [cd]既不区分大小写,也不区分发音符号。
- 正则表达式:MATCHES
检查某个字符串是否匹配指定的正则表达式。虽然正则表达式的执行效率是最低的,但其功能是最强大的,也是我们最常用的。
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", regex];
正则表达式的实际应用的几种方法:
- 判断字符串首字母是否为字母
NSString *regex = @"[A-Za-z]+";
- 以A开头,e结尾
NSString *regex = @"^A.+e
- 手机号码格式:
* 移动:134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188
* 联通:130,131,132,152,155,156,185,186
* 电信:133,1349,153,180,189
NSString * regex M = @"^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$";//中国移动:China Mobile
NSString * regex CM = @"^1(34[0-8]|(3[5-9]|5[017-9]|8[278])\\d)\\d{7}$";//中国联通:China Unicom
NSString * regex CU = @"^1(3[0-2]|5[256]|8[56])\\d{8}$";//中国电信:China Telecom
NSString * regex CT = @"^1((33|53|8[09])[0-9]|349)\\d{7}$";//大陆地区固话及小灵通
- 验证email
NSString *strRegex = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{1,5}";
- 密码组合中要有大写、小写、数字组合:
(?=.*[0-9])(?=.*[a-z])(?=.*[!@#$%^&*])(?=.*[A-Z]).{6,16}
二、使用谓词过滤集合
程序会自动遍历其元素,它会将自动遍历过之后返回为YES的值重新组合成一个集合返回。
- NSArray提供了如下方法使用谓词来过滤集合
- (NSArray*)filteredArrayUsingPredicate:(NSPredicate *)predicate:
使用指定的谓词过滤NSArray集合,返回符合条件的元素组成的新集合
- NSMutableArray提供了如下方法使用谓词来过滤集合
- (void)filterUsingPredicate:(NSPredicate *)predicate:
使用指定的谓词过滤NSMutableArray,剔除集合中不符合条件的元素
- NSSet提供了如下方法使用谓词来过滤集合
- (NSSet*)filteredSetUsingPredicate:(NSPredicate *)predicate NS_AVAILABLE(10_5, 3_0):作用同NSArray中的方法
- NSMutableSet提供了如下方法使用谓词来过滤集合
- (void)filterUsingPredicate:(NSPredicate *)predicate NS_AVAILABLE(10_5, 3_0):
作用同NSMutableArray中的方法。
通过上面的描述可以看出,使用谓词过滤不可变集合和可变集合的区别是:过滤不可变集合时,会返回符合条件的集合元素组成的新集合;过滤可变集合时,没有返回值,会直接剔除不符合条件的集合元素(不可变是返回符合的集合元素,可变是剔除不符合。)
三、在谓词中使用占位符参数
想在谓词表达式中使用变量,那么我们需要了解下列三种占位符:
- %K:用于动态传入属性名:变量名
- %@:用于动态设置属性值:变量值
- $VALUE:动态改变的属性值:可以根据你的需要写不同的值,但是必须有$开头
[NSPredicate predicateWithFormat:@"%K CONTAINS %@", @”name”, @”Jack”];
- //作用:将数组中的name(key)取出含有Jack的组成新数组。
NSPredicate *predTemp = [NSPredicate predicateWithFormat:@"%K > $VALUE", @"age"];//将数组中的age(key)取出大于value的组成新数组
NSPredicate *pred1 = [predTemp predicateWithSubstitutionVariables:@{@"VALUE" : @25}];
//设置value为25,所以就是在数组age(key中取出大于25的组成新数组。
NSArray *newArray1 = [array filteredArrayUsingPredicate:pred1];
// 修改$VALUE的值为32
NSPredicate *pred2 = [predTemp predicateWithSubstitutionVariables:@{@"VALUE" : @32}]; // 修改$VALUE的值为32
NSArray *newArray2 = [array filteredArrayUsingPredicate:pred2];
//设置value为32,所以就是在数组age(key中取出大于32的组成新数组,
所以$VALUE可以根据你的需要写不同的值
上面命令在下面数组运行:
数组:NSArray *array = @[[ZLPersonModel personWithName:@"Jack" age:20 sex:ZLPersonSexMale], [ZLPersonModel personWithName:@"Rose" age:22 sex:ZLPersonSexFamale],
[ZLPersonModel personWithName:@"Jackson" age:30 sex:ZLPersonSexMale],
[ZLPersonModel personWithName:@"Johnson" age:35 sex:ZLPersonSexMale]];
对应的数组输出为:
- "[name = Jack, age = 20, sex = 0]",
"[name = Jackson, age = 30, sex = 0]"
- "[name = Jackson, age = 30, sex = 0]",
"[name = Johnson, age = 35, sex = 0]"
- "[name = Johnson, age = 35, sex = 0]"
搜索框的实现
要实现的协议:<UISearchBarDelegate,UISearchResultsUpdating>
#import "ViewController.h"
//全部数据
@property(strong,nonatomic)NSArray *listData;
//过滤后的数组
@property(strong,nonatomic)NSMutableArray *listFilterData;
@property(strong,nonatomic)UISearchController *searchController;
//内容过滤方法
-(void)filterContentsForSearchText:(NSString*)searchText scope:(NSUInteger)scope;
#import "ViewController.m"
//初次进入查询所有数据
[self filterContentsForSearchText:@"" scope:-1];
//实例化UISearchController
self.searchController=[[UISearchController alloc]initWithSearchResultsController:nil];
//设置self为更新搜索结果对象
self.searchController.searchResultsUpdater=self;
//设置搜索背景为灰色
self.searchController.dimsBackgroundDuringPresentation=false;
//设置搜索范围栏中的按钮
self.searchController.searchBar.scopeButtonTitles=@[@"中文",@"英文"];
/设置实现代理
self.searchController.searchBar.delegate=self;
/将搜索栏放在表头中
self.tableView.tableHeaderView=self.searchController.searchBar;
//尺寸自适应
[self.searchController.searchBar sizeToFit];
}
-(void)filterContentsForSearchText:(NSString *)searchText scope:(NSUInteger)scope{
if ([searchText length]==0) {
//查询所有
self.listFilterTeams=[NSMutableArray arrayWithArray:self.listTeams];
return;
}
NSPredicate *scopePredicate;
NSArray *tempArray;
switch (scope) {
case 0://字段为name的字符串
scopePredicate=[NSPredicate predicateWithFormat:@"SELF.name contains[c]%@",searchText];
//若是只有一个key,则直接用SELF就可以了,如果有多个key(name,image等等),就要明确选择要搜索的key
tempArray=[self.listTeams filteredArrayUsingPredicate:scopePredicate];
self.listFilterTeams=[NSMutableArray arrayWithArray:tempArray];
break;
case 1:
scopePredicate=[NSPredicate predicateWithFormat:@"SELF.image contains[c]%@",searchText];
tempArray=[self.listTeams filteredArrayUsingPredicate:scopePredicate];
self.listFilterTeams=[NSMutableArray arrayWithArray:tempArray];
break;
default:
self.listFilterTeams=[NSMutableArray arrayWithArray:self.listTeams];
break;
}
}
-(void)searchBar:(UISearchBar *)searchBar selectedScopeButtonIndexDidChange:
(NSInteger)selectedScope{
[self updateSearchResultsForSearchController:
self.searchController];
}
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController{
NSString *searchString=searchController.searchBar.text;
[self filterContentsForSearchText:searchString scope:searchController.searchBar.selectedScopeButtonIndex];
scope [self.tableView reloadData];
}
2.直接用代理实现
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController {
NSString *searchString = [self.searchController.searchBar text];
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];
}
iOS学习之NSPredictae及搜索框的实现的更多相关文章
- IOS第二天-新浪微博 - 添加搜索框,弹出下拉菜单 ,代理的使用 ,HWTabBar.h(自定义TabBar)
********HWDiscoverViewController.m(发现) - (void)viewDidLoad { [super viewDidLoad]; // 创建搜索框对象 HWSearc ...
- 十七、Android学习笔记_Android 使用 搜索框
1.在资源文件夹下创建xml文件夹,并创建一个searchable.xml: android:searchSuggestAuthorityshux属性的值跟实现SearchRecentSuggesti ...
- [分享]IOS开发-简单实现搜索框显示历史记录的本地缓存及搜索历史每次只能获取到一个的解决方案
注:原文:http://www.zhimengzhe.com/IOSkaifa/40433.html 1.首先,我们需要对进行过搜索的textField的输入内容进行一个NSUserDefaults的 ...
- vue学习(十四) 条件搜索框动态查询表中数据 数组的新方法
//html <div id="app"> <label> 名称搜索关键字: <input type="text" clasa=& ...
- iOS开发——UI篇OC篇&TextField作为搜索框的使用
TextField作为搜索框的使用 在iOS开发中我们经常会使用到搜索框,但是有的时候系统自带的搜索框不足以满足我吗想要的功能,这个时候我们就可以使用自定义的搜索框实现想要的功能. 今天就简单的介绍一 ...
- 【好程序员笔记分享】——iOS开发之使用TextField作为搜索框
-iOS培训,iOS学习-------型技术博客.期待与您交流!------------ iOS开发之使用TextField作为搜索框 今天给大家带来一个新的技巧,比如平时我们要使用代码创建一 ...
- 猫猫学iOS 之微博项目实战(5)微博自己定义搜索框searchBar
猫猫分享.必须精品 原创文章.欢迎转载. 转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243 一:效果 用UITextField简单定义一个搜索框 二:调用 ...
- AJ学IOS 之微博项目实战(5)微博自定义搜索框searchBar
AJ分享,必须精品 一:效果 用UITextField简单定义一个搜索框 二:调用: 调用的代码,很简单,直接init就可以,以后加功能自己添加就行了. - (void)viewDidLoad { [ ...
- iOS之搜索框UISearchController的使用(iOS8.0以后替代UISearchBar+display)
在iOS 8.0以上版本中, 我们可以使用UISearchController来非常方便地在UITableView中添加搜索框. 而在之前版本中, 我们还是必须使用UISearchBar + UISe ...
随机推荐
- 《Java并发编程实战》读书笔记
Subsections 线程安全(Thread safety)锁(lock)共享对象对象组合基础构建模块任务执行取消和关闭线程池的使用性能与可伸缩性并发程序的测试显示锁原子变量和非阻塞同步机制 一.线 ...
- 实现一个名为Person的类和它的子类Employee,Employee有两个子类Faculty 和Staff。
(1)Person类中的属性有:姓名name(String类型),地址address(String类型), 电话号码telphone(String类型)和电子邮件地址email(String类型): ...
- Thread join
1.主线程生成并起动了子线程,而子线程里要进行大量的耗时的运算,当主线程处理完其他的事务后,需要用到子线程的处理结果,这个时候就要用到join()方法了. 2.Java Thread中, join() ...
- SC.UI
IController using Microsoft.Practices.Prism.Events; using Microsoft.Practices.Prism.Regions; using M ...
- (转)将cocos2dx项目从VS移植到Eclipse
本文转自:http://www.cnblogs.com/Z-XML/p/3349518.html 引言:我们使用cocos2d-x引擎制作了一款飞行射击游戏,其中创新性地融入了手势识别功能.但是我 们 ...
- 关于Unity四元数相乘先后顺序的问题
在unity中四元数和向量相乘在unity中可以变换旋转.四元数和四元数相乘类似矩阵与矩阵相乘的效果. 矩阵相乘的顺序不可互换,只有特殊条件矩阵才可互换.四元数相乘类似,今天就因为这个问题掉进坑里了, ...
- HTTP抓包神器HTTP Analyzer V7 Build7.5.4汉化+注册机
原版安装包.汉化文件.注册机下载:http://pan.baidu.com/s/1bMv1Si 密码:cqq1 一.安装:下载并安装英文原版 下载页面:http://www.ieinspector. ...
- [转]C#中调用资源管理器(Explorer.exe)打开指定文件夹 + 并选中指定文件 + 调用(系统默认的播放类)软件(如WMP)打开(播放歌曲等)文件
原文:http://www.crifan.com/csharp_call_explorer_to_open_destinate_folder_and_select_specific_file/ C#中 ...
- stoneniqiu 理想就是自己喜欢做,并对社会和他人都有意义的事情!
H5嵌入原生开发小结----兼容安卓与ios的填坑之路 2016-11-19 08:29 by stoneniqiu, 1038 阅读, 8 评论, 收藏, 编辑 一开始听说开发H5,以为就是做适配现 ...
- Bootstrap_响应式网格系统
首先添加CSS样式: [class *= col-]{ background-color: #eee; border: 1px solid #ccc; } [class *= col-] [class ...