前言
为了方便童鞋们更深刻的了解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;
}
心灵鸡汤
一青年途经某地,碰到一位老者,问:“这里如何?”老者反问:“你家乡如何?”青年答:“糟透了!我很讨厌。”老者说:“这里也一样糟。”后来又来了个青年问同样问题,老者也同样反问,青年回答说:“我家乡很好,我很想念。”老者便说:“这里也一样好。”旁听者觉得诧异,问老人家为何前后说法不一致呢?老者说:“你管得着吗?”
难受的时候摸摸自己的胸,告诉自己是个汉子,要坚强~