您的位置:首页 > 产品设计 > UI/UE

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

著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。







内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: