UISearchController的使用和自定义UITableViewCell
最近由于在工作中需要用到搜索框,于是今天重新弄了一个搜索框的demo,这个demo主要说的就是如何去进行模糊查询数据。
搜索框有很多第三方的库,但是对于一些使用次数不多的,我觉的用系统自带的也不错。
另外顺便说一下如何自定义UITableViewCell和对UITableView的一些样式的设计
首先查询的数据,我这边写的是一个联系人的一些基本信息,用一个person类来描述
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
@interface Person : NSObject
@property(nonatomic,copy)NSString *name;
@property(nonatomic,copy)NSString *tel;
@property(nonatomic,copy)NSString *sex;
@property(nonatomic,copy)NSString *address;
@end
NS_ASSUME_NONNULL_END
然后就是对一些UI的基本设置
代理
<UITableViewDelegate,UITableViewDataSource,UISearchControllerDelegate,UISearchResultsUpdating,DeleteBtnDelegate>
@property(nonatomic,strong)UISearchController *search;
@property(nonatomic,strong)UITableView *tableView;
@property(nonatomic,strong)NSMutableArray *dataList;
@property(nonatomic,strong)NSMutableArray *searchList;
//初始化
self.tableView = [[UITableView alloc]init];
//代理
self.tableView.delegate = self;
self.tableView.dataSource = self;
//背景颜色(用于区分单元格之间的间隙)
self.tableView.backgroundColor = [UIColor colorWithRed:239.0/255.0 green:239.0/255.0 blue:239.0/255.0 alpha:1.0];
//设置样式
// self.tableView.separatorStyle = UITableViewCellSelectionStylenon;
//没有数据不显示单元格
self.tableView.tableFooterView = [[UIView alloc]initWithFrame:CGRectZero];
//搜索框的初始化
self.search = [[UISearchController alloc]initWithSearchResultsController:nil];
//代理
self.search.delegate = self;
self.search.searchResultsUpdater = self;
//搜索时,背景变模糊
self.search.obscuresBackgroundDuringPresentation = NO;
//隐藏导航栏
self.search.hidesNavigationBarDuringPresentation = YES;
//位置
self.search.searchBar.frame = CGRectMake(0, 0, self.search.searchBar.frame.size.width, 44.0);
//添加到tableview的header
self.tableView.tableHeaderView = self.search.searchBar;
[self.view addSubview:self.tableView];
[self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.bottom.left.right.equalTo(self.view);
}];
因为我们查询数据,都显示在tableView当中,因此,在设置tableview的数量时,需要判断搜索框是否被激活,包括数据显示在单元格当中,也是需要区分搜索框是否激活
- (NSInteger)tableView:(nonnull UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(self.search.active){
return self.searchList.count;
}else{
return self.dataList.count;
}
}
- (nonnull UITableViewCell *)tableView:(nonnull UITableView *)tableView cellForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
NSString *identifier = @"identifier";
PersonTableViewCell *cell = [[PersonTableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
if(cell == nil){
cell = [tableView dequeueReusableCellWithIdentifier:identifier];
}
if([cell respondsToSelector:@selector(setSeparatorInset:)]){
[cell setSeparatorInset:UIEdgeInsetsZero];
}
if([cell respondsToSelector:@selector(setLayoutMargins:)]){
[cell setLayoutMargins:UIEdgeInsetsZero];
}
cell.delegate = self;
Person *p = [[Person alloc]init];
if(self.search.active){
p = self.searchList[indexPath.row];
cell.name.text = p.name;
cell.sex.text = p.sex;
cell.tel.text = p.tel;
cell.address.text = p.address;
}else{
p = self.dataList[indexPath.row];
cell.name.text = p.name;
cell.sex.text = p.sex;
cell.tel.text = p.tel;
cell.address.text = p.address;
}
return cell;
}
重点
对数据进行模糊查询
NSPredicate是用来 过滤获取的数据类,对于一些正则表达式的描述,在这里,我就不详细介绍了。
CONTAINS : 判断字符串内容是否包含搜索的字符串
-(void)updateSearchResultsForSearchController:(UISearchController *)searchController{
NSString *searchString = [self.search.searchBar text];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF.name CONTAINS %@ OR SELF.sex CONTAINS %@ OR SELF.tel CONTAINS %@ OR SELF.address CONTAINS %@",searchString,searchString,searchString,searchString];
if(self.searchList!=nil){
[self.searchList removeAllObjects];
}
//过滤数据
self.searchList = [NSMutableArray arrayWithArray:[self.dataList filteredArrayUsingPredicate:predicate]];
//刷新表格
[self.tableView reloadData];
}
模拟器运行结果
Simulator Screen Shot - iPhone SE (2nd generation) - 2020-04-29 at 16.38.54.png Simulator Screen Shot - iPhone SE (2nd generation) - 2020-04-29 at 16.39.26.png上面两张图是显示的结果。
自定义UITableViewCell
在我们开发中,常常不满足系统的UITableViewCell的格式,因此,我们需要对cell进行自定义
还是按照上面的图片的样式来自定义cell格式
.h文件
#import <UIKit/UIKit.h>
@protocol DeleteBtnDelegate <NSObject>
-(void)deleteMessage:(UITableViewCell *_Nullable)cell;
@end
NS_ASSUME_NONNULL_BEGIN
@interface PersonTableViewCell : UITableViewCell
@property(nonatomic,weak)id<DeleteBtnDelegate>delegate;
@property(nonatomic,strong)UIButton *deleteBtn;
@property(nonatomic,strong)UILabel *name;
@property(nonatomic,strong)UILabel *tel;
@property(nonatomic,strong)UILabel *sex;
@property(nonatomic,strong)UILabel *address;
@end
.m文件
对一些显示的内容初始化,如果你们需要添加其他UI组件,你们可以自行添加,原理都是一样的。
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
if(self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]){
UILabel *name = [[UILabel alloc]init];
[self.contentView addSubview:name];
self.name = name;
UILabel *tel = [[UILabel alloc]init];
[self.contentView addSubview:tel];
self.tel = tel;
UILabel *sex = [[UILabel alloc]init];
[self.contentView addSubview:sex];
self.sex = sex;
UILabel *address = [[UILabel alloc]init];
[self.contentView addSubview:address];
self.address = address;
UIButton *deleteBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[deleteBtn setTitle:@"删除" forState:UIControlStateNormal];
[deleteBtn addTarget:self action:@selector(deleteMessage:) forControlEvents:UIControlEventTouchUpInside];
[self.contentView addSubview:deleteBtn];
self.deleteBtn = deleteBtn;
}
return self;;
}
在layoutSubviews对UI组件的位置进行设置
这边我使用的是masnory进行布局,你们也可以用frame来布局,都一样。
-(void)layoutSubviews{
[super layoutSubviews];
[self.name mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.equalTo(self).offset(10);
}];
[self.sex mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.equalTo(self.name).offset(20);
make.left.equalTo(self).offset(10);
}];
[self.tel mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.equalTo(self.sex).offset(20);
make.left.equalTo(self).offset(10);
}];
[self.address mas_makeConstraints:^(MASConstraintMaker *make) {
make.top.left.equalTo(self.tel).offset(20);
make.left.equalTo(self).offset(10);
}];
[self.deleteBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self).offset(-10);
make.top.bottom.equalTo(self);
}];
}
对cell之间的距离进行设置,
重写-(void)setFrame:(CGRect)frame方法
在自定义cell中,可以用这种方法来设置cell之间的距离,若不自定义,可以对每个数据进行分组,设置每个分组之间的距离也行。
-(void)setFrame:(CGRect)frame{
//单元格距离左边屏幕的距离
//frame.origin.x +=10;
//单元格距离上边屏幕的距离
//frame.origin.y +=10;
//单元格下面与下一个单元格之间的距离
frame.size.height -=10;
//单元格距离右边屏幕设置的距离
//frame.size.width -=20;
[super setFrame:frame];
}
按钮的代理方法的实现
-(void)deleteMessage:(UITableViewCell *_Nullable)cell{
[self.delegate deleteMessage:self];
}
我也是小白一个,若有错误,请指正!谢谢
网友评论