IOS中Table View控件练习(表视图,自定义cell,分组,索引,搜索)
之前两篇博客简单学习了Picker view控件的使用,接下来再学习IOS应用中很重要的一个视图--表视图。
在表视图中,每个表视图都是UITableView的一个实例,每个可见行都是UITableViewCell的一个实例。
表视图有两种基本格式,分组的表和普通表,普通表可以实现索引,实现了索引的表成为索引表。(PS.技术上,分组表也可以实现索引,不过好像苹果的设计规范中不支持)
目录
一个简单的表视图应用
界面设计:
向storyboard中拖一个table view控件,他会自动占满屏幕,至于约束,可以自己创建,记得设置tableview的tag为1,后面会用到。
table view的outlets中会有dataSource和delegate两个设置项,按住每个设置项后面的空心圆,拖向storyboard中的controller按钮,完成关联。
代码讲解:
首先要在对应控制器的.h文件中实现UITableViewDataSource和UITableViewDelegate两个协议。
在.m文件中首先定义一个nsarray类型的属性,这个属性用来存放tableview要显示的数据,并且在viewDidLoad方法中给nsarray赋值。
在viewDidLoad方法中还需要做的是把tableview的顶部向下偏移一定数量来美化界面(算不得美化,如果不做这一步处理,tableview顶部会紧挨着状态栏,很难看<( ̄▽ ̄)> 哇哈哈…)
UITableView* tableView = (id)[self.view viewWithTag:1];//通过tag获取控件 UIEdgeInsets contentInset = tableView.contentInset; contentInset.top = 20; [tableView setContentInset:contentInset];
然后实现两个委托方法,一个是- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section,返回这个table的行数,
另一个是- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath,这个方法会返回指定行的TableViewCell。
首先看看这个方法的参数,第一个参数是一个tableview,表示触发这个方法的table。第二个参数是NSIndexPath类型的值,这个类型有两个主要的属性,section和row,组和行。
创建一个UITableViewCell对象,此处使用的dequeueReusableCellWithIdentifier:方法,这个方法会返回一个可以重用的cell,也有可能返回nil
所以我们要判断返回值,如果返回值为nil,就需要实例化一个cell
有了cell,就能设置cell要显示的文本
cell.textLabel.text = self.dwarves[indexPath.row];
不只可以设置文本,还可以设置图标
UIImage* image = [UIImage imageNamed:@"star"]; cell.imageView.image = image;
imageView除了有image属性外,还有一个hightedImage属性,可以自己设置。
这个程序让所有的行都使用了相同的图标,我们可以根据indexPath中的section和row设置每行的专属图标
行选择事件:
行的选择事件需要在一个委托方法中处理,这个方法是
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
这个方法在行被选择之后调用,可以在这个方法内通过indexPath参数确定所选的组和行,进一步处理,处理完成之后把该行取消选择状态
[tableView deselectRowAtIndexPath:indexPath animated:YES];
上一个方法是在行被选择之后调用,还有一个委托方法会在行被选择之前就调用,这个方法是
-(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath
这个方法里也可以通过indexPath判断用户点击的组和行,进而实现禁止选择某一行。返回nil就是禁止选择了某一行
完整代码:
1 // 2 // ViewController.m 3 // Simple Table 4 // 5 // Created by 张光发 on 15/10/19. 6 // Copyright (c) 2015年 张光发. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 11 @interface ViewController () 12 @property (strong, nonatomic) NSArray* dwarves; 13 @end 14 15 @implementation ViewController 16 17 - (void)viewDidLoad 18 { 19 [super viewDidLoad]; 20 self.dwarves = @[ @"Sleepy", @"Sneezy", @"Bashful", @"Happy", @"Doc", @"Grumpy", @"Dopey", @"Thorin", @"Dorin", @"Nori", @"Ori", @"Balin", @"Dwalin", @"Fili", @"Kili", @"Oin", @"Gloin", @"Bifur", @"Bofur", @"Bombur" ]; 21 UITableView* tableView = (id)[self.view viewWithTag:1]; 22 UIEdgeInsets contentInset = tableView.contentInset; 23 contentInset.top = 20; 24 [tableView setContentInset:contentInset]; 25 } 26 27 - (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section 28 { 29 return [self.dwarves count]; 30 } 31 32 - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath 33 { 34 static NSString* SimpleTableIndetifier = @"SimpleTableIdentfier"; 35 UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:SimpleTableIndetifier]; 36 if (cell == nil) { 37 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIndetifier]; 38 } 39 UIImage* image = [UIImage imageNamed:@"star"]; 40 cell.imageView.image = image; 41 cell.textLabel.text = self.dwarves[indexPath.row]; 42 if (indexPath.row<7) { 43 cell.detailTextLabel.text=@"MR. dIDSNEY"; 44 }else{ 45 cell.detailTextLabel.text=@"mr. Tolkien"; 46 } 47 return cell; 48 } 49 50 //!!!: 选中之前 51 -(NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath 52 { 53 if (indexPath.row==0) { 54 return nil; 55 }else{ 56 return indexPath; 57 } 58 } 59 //!!!: 行被选择时调用 60 -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 61 { 62 NSString *rowValue=self.dwarves[indexPath.row]; 63 NSString *message=[[NSString alloc] initWithFormat:@"你选择的是%@",rowValue]; 64 UIAlertView *alert=[[UIAlertView alloc] initWithTitle:@"Row Selected!" message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil]; 65 [alert show]; 66 //取消行选中状态 67 [tableView deselectRowAtIndexPath:indexPath animated:YES]; 68 } 69 @end
自定义Cell的tableView
思路:
两种自定义cell的方式,一种是使用代码布局的,一种是从nib文件加载,两种方式最终实现的效果是一样的
实现的原理就是单独设计Cell的界面,然后把设计好的cell界面当做子view使用,记着设计好公开属性或接口,让tableview赋值
使用代码布局的方式:
新建一个cocoa touch class,命名为NameAndColorCell,subclass of选择UITableViewCell
在.h文件公开两个NSString属性,name和color
在.m文件中设计两个私有UILable属性,nameLabel和colorLabel,然后实现一个方法
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)reuseIdentifier
在tableview加载cell时会调用这个方法,这个方法实现的内容就是布局
首先初始化self,因为本类继承自UITableViewCell,所以初始化self的方法就是调用父类中的初始化方法
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
然后添加2个uilabel,并设置NameAndColorCell类中的所有uilabel(包括2个私有的uilabel),并把它们添加到self.contentView中,因为contentView管理着cell的所有子视图,所以要添加到这里,而不是直接添加到cell。
重写setName:(NSString *)name和setColor:(NSString *)color方法,
判断如果当前实例的公开属性_name不等于要设置的name,就设置私有属性nameLabel的text为name,color同理。文字描述有点绕,看看代码吧
- (void)setName:(NSString*)name { if (![name isEqualToString:_name]) {
//为什么不直接设置nameLabel.text=name?请各路大哥解答,感激不尽 _name = [name copy]; self.nameLabel.text = _name; } }
这样cell子视图就写完了,下面要编写主控制器中的代码。
主控制器.m文件要引用cell类,使用
#import "NameAndColorCell.h"
定义一个静态nsstring,后面会用到多次,防止拼写错误,内容可以自己定义
static NSString *CellTableIdentifier = @"CellTableIdentifier";
定义一个nsarray类型的属性,作为tableview的数据,并在viewDidLoad中给这个属性赋值
除此之外,还应该在viewDidLoad方法中告诉tableview应该怎样加载cell
UITableView *tableView = (id)[self.view viewWithTag:1]; //???: 告诉tableview应该从哪里加载cell [tableView registerClass:[NameAndColorCell class] forCellReuseIdentifier:CellTableIdentifier];
记得把tableview的顶部向下偏移一段距离,要不然很丑~>_<~
最后记得实现两个数据源方法,
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 和
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
第二个方法是返回指定indexpath的cell,
因为我们是自定义cell,所以初始化一个cell类,
NameAndColorCell *cell =
[tableView dequeueReusableCellWithIdentifier:CellTableIdentifier forIndexPath:indexPath];
然后根据indexPath.row获取行数据,赋值给cell中的name和color
NSDictionary *rowData = self.computers[indexPath.row]; cell.name = rowData[@"Name"]; cell.color = rowData[@"Color"];
最后返回这个cell实例既可。
完整代码:
主控制器.m
1 // 2 // ViewController.m 3 // Cells 4 // 5 // Created by 张光发 on 15/10/20. 6 // Copyright (c) 2015年 张光发. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 #import "NameAndColorCell.h" 11 12 static NSString *CellTableIdentifier = @"CellTableIdentifier"; 13 14 @interface ViewController () 15 @property(copy, nonatomic) NSArray *computers; 16 @end 17 18 @implementation ViewController 19 20 - (void)viewDidLoad { 21 [super viewDidLoad]; 22 self.computers = @[ 23 @{ 24 @"Name" : @"MacBook Air", 25 @"Color" : @"Silver" 26 }, 27 @{ 28 @"Name" : @"MacBook Pro", 29 @"Color" : @"Silver" 30 }, 31 @{ 32 @"Name" : @"iMac", 33 @"Color" : @"Silver" 34 }, 35 @{ 36 @"Name" : @"Mac Mini", 37 @"Color" : @"Silver" 38 }, 39 @{ 40 @"Name" : @"Mac Pro", 41 @"Color" : @"Black" 42 } 43 ]; 44 UITableView *tableView = (id)[self.view viewWithTag:1]; 45 //???: 告诉tableview应该从哪里加载cell 46 [tableView registerClass:[NameAndColorCell class] 47 forCellReuseIdentifier:CellTableIdentifier]; 48 49 UIEdgeInsets contentInset = tableView.contentInset; 50 contentInset.top = 20; 51 [tableView setContentInset:contentInset]; 52 } 53 54 - (NSInteger)tableView:(UITableView *)tableView 55 numberOfRowsInSection:(NSInteger)section { 56 return [self.computers count]; 57 } 58 59 - (UITableViewCell *)tableView:(UITableView *)tableView 60 cellForRowAtIndexPath:(NSIndexPath *)indexPath { 61 NameAndColorCell *cell = 62 [tableView dequeueReusableCellWithIdentifier:CellTableIdentifier 63 forIndexPath:indexPath]; 64 NSDictionary *rowData = self.computers[indexPath.row]; 65 66 cell.name = rowData[@"Name"]; 67 cell.color = rowData[@"Color"]; 68 69 return cell; 70 } 71 72 @end
cell视图.m
1 // 2 // NameAndColorCell.m 3 // 4 // 5 // Created by 张光发 on 15/10/20. 6 // 7 // 8 9 #import "NameAndColorCell.h" 10 @interface NameAndColorCell () 11 @property (strong, nonatomic) UILabel* nameLabel; 12 @property (strong, nonatomic) UILabel* colorLabel; 13 @end 14 15 @implementation NameAndColorCell 16 17 - (void)awakeFromNib 18 { 19 // Initialization code 20 } 21 22 - (void)setSelected:(BOOL)selected animated:(BOOL)animated 23 { 24 [super setSelected:selected animated:animated]; 25 26 // Configure the view for the selected state 27 } 28 29 - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)reuseIdentifier 30 { 31 self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 32 if (self) { 33 CGRect nameLabelRect = CGRectMake(0, 5, 70, 15); 34 UILabel* nameMarker = [[UILabel alloc] initWithFrame:nameLabelRect]; 35 nameMarker.textAlignment = NSTextAlignmentRight; 36 nameMarker.text = @"Name"; 37 nameMarker.font = [UIFont boldSystemFontOfSize:12]; 38 [self.contentView addSubview:nameMarker]; 39 40 CGRect colorLabelRect = CGRectMake(0, 25, 70, 15); 41 UILabel* colorMarker = [[UILabel alloc] initWithFrame:colorLabelRect]; 42 colorMarker.textAlignment = NSTextAlignmentRight; 43 colorMarker.text = @"Color"; 44 colorMarker.font = [UIFont boldSystemFontOfSize:12]; 45 [self.contentView addSubview:colorMarker]; 46 47 CGRect nameValueRect = CGRectMake(80, 5, 200, 15); 48 _nameLabel = [[UILabel alloc] initWithFrame:nameValueRect]; 49 [self.contentView addSubview:_nameLabel]; 50 51 CGRect colorValueRect = CGRectMake(80, 25, 200, 15); 52 _colorLabel = [[UILabel alloc] initWithFrame:colorValueRect]; 53 [self.contentView addSubview:_colorLabel]; 54 } 55 return self; 56 } 57 58 - (void)setName:(NSString*)name 59 { 60 if (![name isEqualToString:_name]) { 61 _name = [name copy]; 62 self.nameLabel.text = _name; 63 } 64 } 65 - (void)setColor:(NSString*)color 66 { 67 if (![color isEqualToString:_color]) { 68 _color = [color copy]; 69 self.colorLabel.text = _color; 70 } 71 } 72 @end
使用nib布局:
首先把上面的子视图.m文件中定义的两个私有uilabel改为接口,既IBOutlet
在上面的基础上,添加一个user interface组中empty类型的文件,并命名为NameAndColorCell,
这个nib文件是空白的,首先在文件检查器中取消自动布局。
拖一个tableviewcell,并在属性检查器中设置identifier为"CellTableIdentifier",这是为了和上面的代码一致。
拖出4个uilabel,排列并设置好字体等信息。
在身份检查器中设置class为NameAndColorCell.在关联检查器中应该就能看到第一步更改的两个输出接口了,按住后面的空心圆拖到对应的uilabel上。
这些操作的意义就是代替了子视图.m文件中的
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString*)reuseIdentifier方法。
在主视图.m文件中的viewDidLoad方法中删除之前的
[tableView registerClass:[NameAndColorCell class] forCellReuseIdentifier:CellTableIdentifier];
因为这是使用代码布局的,我们现在要使用nib文件布局,所以修改为
UINib *nib=[UINib nibWithNibName:@"NameAndColorCell" bundle:nil]; [tableView registerNib:nib forCellReuseIdentifier:CellTableIdentifier];
其他的不变,这样就是使用了nib文件布局。因为代码改动较少,而且不难,这里就不贴源码了。
表视图分组和索引
界面布局:
使用single view application 模板,在main.storyboard中拖一个tableview放在场景中,设置约束,在属性检查器中设置style为grouped,关联delegate和dataSource关联。
代码讲解:
在.h文件中继承UITableViewDelegate,UITableViewDataSource协议。
这次例子用到的数据太多,提供一个plist,点击下载
这个plist文件中按照字母分组,每个字母下有许多对应字母开头的名字。
定义一个静态nsstring,用作cell的标识,内容随意。
定义两个属性,一个是NSDictionary *name,另一个是NSArray* keys。
name加载的所有数据,keys只存放了组名称。
在viewDidLoad中要做的工作就是给tableview注册cell,把plist文件中的数据加载到name和keys中。
然后实现几个UITableViewDataSource中的方法,来设置tableview的一些属性
1 //TODO: 返回组数 2 - (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView 3 { 4 return [self.names count]; 5 } 6 7 //TODO: 返回指定组的行数 8 - (NSInteger)tableView:(UITableView*)tableView 9 numberOfRowsInSection:(NSInteger)section 10 { 11 NSString* key = self.keys[section]; 12 NSArray* nameSection = self.names[key]; 13 return [nameSection count]; 14 } 15 16 //TODO: 返回指定组的组标题 17 - (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section 18 { 19 return self.keys[section]; 20 } 21 22 //TODO: 返回指定位置的cell 23 - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath 24 { 25 UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier forIndexPath:indexPath]; 26 //获取组名 27 NSString* key = self.keys[indexPath.section]; 28 //获取对应组名下的所有名字 29 NSArray* nameSection = self.names[key]; 30 //获取并设置指定行的名字 31 cell.textLabel.text = nameSection[indexPath.row]; 32 return cell; 33 }
这样就完成了表视图的分组,主要还是数据。
添加索引:
把tableview的style设置为plain,实现另一个UITableViewDataSource中的方法
- (NSArray*)sectionIndexTitlesForTableView:(UITableView*)tableView
这个方法就给tableview添加了索引,返回的nsarray就是索引的内容,所以这里返回keys就可以了。
程序优化:
tableview的style成为plain之后,又出现了之前状态栏干扰问题,所以要在viewDidLoad中判断tableview的style,如果是plain就让tableview向下偏移一定距离。
另一个问题是列表滚动的时候,内容会穿过状态栏,效果很难看,所以我们添加一个透明的view放在状态栏,这样就能大大美化这个现象。
UIView* backView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 20)]; backView.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.9];
[self.view addSubview:backView];
完整代码:
1 // 2 // ViewController.m 3 // Sections 4 // 5 // Created by 张光发 on 15/10/22. 6 // Copyright (c) 2015年 张光发. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 static NSString* SectionsTableIdentifier = @"SectionTableIdentifier"; 11 12 @interface ViewController () 13 @property (copy, nonatomic) NSDictionary* names; 14 @property (copy, nonatomic) NSArray* keys; 15 @end 16 17 @implementation ViewController 18 19 - (void)viewDidLoad 20 { 21 [super viewDidLoad]; 22 23 UITableView* tableView = (id)[self.view viewWithTag:1]; 24 [tableView registerClass:[UITableViewCell class] 25 forCellReuseIdentifier:SectionsTableIdentifier]; 26 27 NSString* path = 28 [[NSBundle mainBundle] pathForResource:@"sortednames" 29 ofType:@"plist"]; 30 self.names = [NSDictionary dictionaryWithContentsOfFile:path]; 31 self.keys = 32 [[self.names allKeys] sortedArrayUsingSelector:@selector(compare:)]; 33 34 if (tableView.style == UITableViewStylePlain) { 35 UIEdgeInsets contentInset = tableView.contentInset; 36 contentInset.top = 20; 37 [tableView setContentInset:contentInset]; 38 39 UIView* backView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 20)]; 40 backView.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.9]; 41 [self.view addSubview:backView]; 42 } 43 } 44 45 //TODO: 返回组数 46 - (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView 47 { 48 return [self.names count]; 49 } 50 51 //TODO: 返回指定组的行数 52 - (NSInteger)tableView:(UITableView*)tableView 53 numberOfRowsInSection:(NSInteger)section 54 { 55 NSString* key = self.keys[section]; 56 NSArray* nameSection = self.names[key]; 57 return [nameSection count]; 58 } 59 60 //TODO: 返回指定组的组标题 61 - (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section 62 { 63 return self.keys[section]; 64 } 65 66 //TODO: 返回指定位置的cell 67 - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath 68 { 69 UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier forIndexPath:indexPath]; 70 //获取组名 71 NSString* key = self.keys[indexPath.section]; 72 //获取对应组名下的所有名字 73 NSArray* nameSection = self.names[key]; 74 //获取并设置指定行的名字 75 cell.textLabel.text = nameSection[indexPath.row]; 76 return cell; 77 } 78 79 //TODO: 增加索引,返回索引内容 80 - (NSArray*)sectionIndexTitlesForTableView:(UITableView*)tableView 81 { 82 return self.keys; 83 } 84 @end
表视图添加搜索栏
我看完课本上的搜索发现课本用的过时的搜索方法,既uisearchdisplaycontroller和uisearchbar配合的方法,这样的方法在ios8已经不推荐了,所以我在查找新的方法,使用uisearchcontroller代替,今晚偷懒看个电影,还没整理好,明天周六更新^-^
对了,明天去鼓楼小吃街吃卤煮、爆肚、炒肝,各位不要羡慕哟,哈哈
------------------------------------------------------华丽丽的分割线------------------------------------------------------
今天去鼓楼转了转,吃了不少好吃的,看到不少漂亮妹子 Y^o^Y
晚上回来没忘了昨天的搜索,百度之后整理了一下,写下来吧,使用UISearcherController,原因上面说到了。
主要参考了推酷上一篇文章,文章链接
界面设计方面和之前的一样,只需要一个tableview,这里就不再说了。
代码讲解:
.h文件中,继承UITableViewDataSource,UITableViewDelegate,UISearchBarDelegate,UISearchResultsUpdating 4个协议。
.m文件中定义3个属性,NSMutableArray* dataList,NSMutableArray* searchList,UISearchController* searchController。
其中,dataList是存储的所有数据,searchList存储的搜索结果,sracherController就是实现搜索功能要用到的。
在viewDidLoad方法中,首先生成数据,设置tableview的偏移量,添加状态栏遮罩(上面说到了),
然后初始化searcherController,并设置一些属性
1 _searchController = [[UISearchController alloc] initWithSearchResultsController:nil]; 2 //显示搜索结果的控制器,必要 3 _searchController.searchResultsUpdater = self; 4 //搜索时底层内容是否显示灰色 5 _searchController.dimsBackgroundDuringPresentation = NO; 6 //搜索时导航栏是否隐藏 7 _searchController.hidesNavigationBarDuringPresentation = NO; 8 //搜索栏的位置、大小信息,必要 9 _searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, self.searchController.searchBar.frame.origin.y, self.searchController.searchBar.frame.size.width, 44.0);
之后就是实现一些代理方法,其中最重要的一个是
- (void)updateSearchResultsForSearchController:(UISearchController*)searchController
这个方法将在搜索栏成为第一响应者或者搜索内容发生变化时调用,其内部实现的主要是搜索规则和显示搜索结果。
获取搜索关键字并根据关键字创建搜索规则,规则是创建了NSPredicate类型的一个变量,关于后面规则的语法可以参考CSDN的这篇博客
//获取搜索关键字 NSString* searchString = searchController.searchBar.text; //设置搜索规则,此处是字符串包含关键字 NSPredicate* predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[c] %@", searchString];
记得清除上一次的搜索结果
//清除旧的搜索结果 if (self.searchList != nil) { [self.searchList removeAllObjects]; }
然后利用之前创建的搜索规则对tableview中显示的所有数据过滤,把过滤结果添加到searchList中,并让tableview重新加载
//验证数据,并把通过的数据添加到搜索结果中 self.searchList = [NSMutableArray arrayWithArray:[_dataList filteredArrayUsingPredicate:predicate]]; //重新加载tableview UITableView* tableView = (id)[self.view viewWithTag:1]; [tableView reloadData];
这样就完成了最简单的搜索功能,复杂的可以在- (void)updateSearchResultsForSearchController:(UISearchController*)searchController中扩展。
完整代码:
1 // 2 // ViewController.m 3 // TableView Search 4 // 5 // Created by 张光发 on 15/10/24. 6 // Copyright (c) 2015年 张光发. All rights reserved. 7 // 8 9 #import "ViewController.h" 10 11 @interface ViewController () 12 @property (strong, nonatomic) UISearchController* searchController; 13 @property (strong, nonatomic) NSMutableArray* dataList; 14 @property (strong, nonatomic) NSMutableArray* searchList; 15 @end 16 17 @implementation ViewController 18 19 - (void)viewDidLoad 20 { 21 [super viewDidLoad]; 22 23 self.dataList = [[NSMutableArray alloc] init]; 24 for (int i = 0; i < 100; i++) { 25 [self.dataList addObject:[NSString stringWithFormat:@"minions %d号🍌", i]]; 26 } 27 UITableView* tableView = (id)[self.view viewWithTag:1]; 28 UIEdgeInsets tableInset = tableView.contentInset; 29 tableInset.top = 20; 30 tableView.contentInset = tableInset; 31 32 UIView* backView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, [[UIApplication sharedApplication] statusBarFrame].size.height)]; 33 backView.backgroundColor = [UIColor colorWithWhite:1.0 alpha:0.9]; 34 [self.view addSubview:backView]; 35 36 _searchController = [[UISearchController alloc] initWithSearchResultsController:nil]; 37 //显示搜索结果的控制器,必要 38 _searchController.searchResultsUpdater = self; 39 //搜索时底层内容是否显示灰色 40 _searchController.dimsBackgroundDuringPresentation = NO; 41 //搜索时导航栏是否隐藏 42 _searchController.hidesNavigationBarDuringPresentation = NO; 43 //搜索栏的位置、大小信息,必要 44 _searchController.searchBar.frame = CGRectMake(self.searchController.searchBar.frame.origin.x, self.searchController.searchBar.frame.origin.y, self.searchController.searchBar.frame.size.width, 44.0); 45 tableView.tableHeaderView = self.searchController.searchBar; 46 } 47 48 //TODO: 返回组数 49 - (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView 50 { 51 return 1; 52 } 53 54 //TODO: 返回行数 55 - (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section 56 { 57 if (self.searchController.active) { 58 return [self.searchList count]; 59 } 60 else { 61 return [self.dataList count]; 62 } 63 } 64 65 //TODO: 选择行之后调用 66 - (void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath 67 { 68 //取消行的选择状态 69 [tableView deselectRowAtIndexPath:indexPath animated:YES]; 70 } 71 72 //TODO: 返回对应位置的cell 73 - (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath 74 { 75 static NSString* flag = @"cellFlag"; 76 UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:flag]; 77 if (cell == nil) { 78 cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:flag]; 79 } 80 if (self.searchController.active) { 81 [cell.textLabel setText:self.searchList[indexPath.row]]; 82 } 83 else { 84 [cell.textLabel setText:self.dataList[indexPath.row]]; 85 } 86 return cell; 87 } 88 89 //TODO: 搜索栏成为第一响应者或者搜索内容发生变化时调用 90 - (void)updateSearchResultsForSearchController:(UISearchController*)searchController 91 { 92 //获取搜索关键字 93 NSString* searchString = searchController.searchBar.text; 94 //设置搜索规则,此处是字符串包含关键字 95 NSPredicate* predicate = [NSPredicate predicateWithFormat:@"SELF CONTAINS[c] %@", searchString]; 96 //清除旧的搜索结果 97 if (self.searchList != nil) { 98 [self.searchList removeAllObjects]; 99 } 100 //验证数据,并把通过的数据添加到搜索结果中 101 self.searchList = [NSMutableArray arrayWithArray:[_dataList filteredArrayUsingPredicate:predicate]]; 102 103 //重新加载tableview 104 UITableView* tableView = (id)[self.view viewWithTag:1]; 105 [tableView reloadData]; 106 } 107 108 @end
效果图:


浙公网安备 33010602011771号