美文网首页
UISearchController的使用和自定义UITable

UISearchController的使用和自定义UITable

作者: 大橘猪猪侠 | 来源:发表于2020-04-29 16:53 被阅读0次

    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];
    }
    

    我也是小白一个,若有错误,请指正!谢谢

    相关文章

      网友评论

          本文标题:UISearchController的使用和自定义UITable

          本文链接:https://www.haomeiwen.com/subject/kzdnwhtx.html