程序人生

UITableView比较全面的使用

2019-04-02  本文已影响4人  小石头呢

一.数据解析

plist文件结构
数组里面放着字典,字典里面放着一个字符串和关于车子信息的数组
这可以看成两个模型,里面的数组是一个模型,外面的数组也是一个模型
形成了模型嵌套模型的结果 Class Prefix
为了区分自己定义的类和系统定义的类,可以选中工程在右边找到Class Prefix为自己创建的类设置一个标识,比如名字首字母缩写 文件分组管理

开发过程中文件过多,我们需要按照一定规则将文件放在不同的文件夹中管理,比如我这里只有一个界面且使用的是MVC方式构建,所以就可以创建Model,View,Controller三个文件夹
遇到多个界面,可以先创建界面文件夹在在相应文件夹下面创建文件夹

1.创建两个模型,CarGroupModel和CarModel,并且自己提供好加载数据的方法
我们可以用<类名 *>放在不明确的地方,比如我这里的NSArray

#import <Foundation/Foundation.h>
#import "XLCarModel.h"

@interface XLCarGroupModel : NSObject

/**小组名*/
@property (nonatomic,copy) NSString *title;

/**小组内容*/
@property (nonatomic,copy) NSArray<XLCarModel *> *cars;

//自己提供加载数据的方法
+(NSArray<XLCarGroupModel *> *)loaData;

@end


#import <Foundation/Foundation.h>

@interface XLCarModel : NSObject

/**模型图片*/
@property (nonatomic,copy) NSString *icon;

/**模型名*/
@property (nonatomic,copy) NSString *name;

@end

2.手动解析数据

+(NSArray<XLCarGroupModel *> *)loaData{

    //获取plist文件路径
    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"cars_total.plist" ofType:nil];
    //获取文件的内容
    NSArray *groupArray = [NSArray arrayWithContentsOfFile:filePath];
    //NSLog(@"%@",groupModel);

    //定义数组 保存所有group模型数据
    NSMutableArray *groupModelsArray = [NSMutableArray array];

    //手动解析数据 封装为模型

    for (NSDictionary *groupDic in groupArray) {

        //一个group对应一个model
        XLCarGroupModel *groupModel = [[XLCarGroupModel alloc] init];

        //解析属性
        //title
        groupModel.title = [groupDic objectForKey:@"title"];

        //通过关键字cars获取车的所有信息
        NSArray *carsArray = [groupDic objectForKey:@"cars"];

        //创建数组保存所有车的模型数据
        NSMutableArray *carModelsArray = [NSMutableArray array];

        //将每一个车的信息封装为model类型
        for (NSDictionary *carDic in carsArray) {

            //创建车的模型对象
            XLCarModel *carModel = [[XLCarModel alloc] init];

            //解析属性
            //icon
            carModel.icon = [carDic objectForKey:@"icon"];
            //name
            carModel.name = [carDic objectForKey:@"name"];
            
            //将carModel模型添加到模型数组中
            [carModelsArray addObject:carModel];
        }

        //解析属性
        //cars
        groupModel.cars = carModelsArray;

        //将groupModel模型添加到模型数组中
        [groupModelsArray addObject:groupModel];

    }

    return groupModelsArray;
}

3.利用MJExtension解析数据

+(NSArray<XLCarGroupModel *> *)loaData{
    
    //模型中包含一个数组 数组中是另一个模型数组
    //在转化之前需要告诉转化器 这个cars数组里面到底是什么
    [XLCarGroupModel mj_setupObjectClassInArray:^NSDictionary *{
        return @{@"cars":@"XLCarModel"};
    }];
    
    //数据转模型 我只需要告诉你我的数据在哪个文件里面
    NSArray *groupModelsArray = [XLCarGroupModel mj_objectArrayWithFilename:@"cars_total.plist"];
    
    //NSLog(@"%@",groupModelsArray);
    
    return groupModelsArray;
}

二.根据数据显示内容

1.创建UITableView并设置代理

    //加载数据
    self.groupModelsArray =  [XLCarGroupModel loaData];
    //创建
    self.tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStyleGrouped];
    //配置
    _tableView.delegate = self;
    _tableView.dataSource = self;
    //显示
    [self.view addSubview:_tableView];

2.配置tableView有多少个section以及每个section有多少个row,以及每个section的title

//设置有多少个section
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    
    return _groupModelsArray.count;
}

//设置每个section有多少个row
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    
    //取出section对应的模型数据
    XLCarGroupModel *model = [_groupModelsArray objectAtIndex:section];
    
    return model.cars.count;
}

//设置每个section的title
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
    
    //取出section对应的模型数据
    XLCarGroupModel *model = [_groupModelsArray objectAtIndex:section];
    
    return model.title;
}

3.设置索引列表

//设置索引列表
-(NSArray<NSString *> *)sectionIndexTitlesForTableView:(UITableView *)tableView{
    
//    //1.遍历所有的groupmodel 获取title
//    NSMutableArray *titlesArray = [NSMutableArray array];
//    
//    for (XLCarGroupModel *groupModel in _groupModelsArray) {
//        [titlesArray addObject:groupModel.title];
//    }
//    
//    //2.kvc
    
    return [_groupModelsArray valueForKey:@"title"];
}

4.配置cell高度

//设置cell的高度
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 60;
}

三.设置每个row显示什么什么样的UITableViewCell

1.使用默认的UITableViewCell创建
a.常规方法

//设置每个row显示什么内容
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    //1.从队列里面获取重复利用的cell 标识符为cellID
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellID"];

    //2.判断tableview队列里面是否有可以利用的cell
    if (cell == nil) {
        //没有可以重复利用的cell
        //创建 添加标记
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cellID"];
    }

    //对cell的赋值必须放在创建的外面
    //在消失的时候 或被原样扔到队列里面去
    //重复利用时 需要显示新的内容

    //取出section对应的group模型
    XLCarGroupModel *model = [_groupModelsArray objectAtIndex:indexPath.section];

    //取出row对应的car模型
    XLCarModel *carModel = [model.cars objectAtIndex:indexPath.row];

    //获得图片
    cell.imageView.image = [UIImage imageNamed:carModel.icon];

    //获得名字
    cell.textLabel.text = carModel.name;

    return cell;
}

b.减少代码量的方法

先在viewDidload里面注册
//注册一下tableView需要显示的cell的类型和对应的标识符
//当重复利用的队列里面没有重复利用的cell
//tableView就会自动创建一个设定的class类型的cell,并添加标识符
[_tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cellID"];

配置cell
//设置每个row显示什么内容
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellID"];

    //对cell的赋值必须放在创建的外面
    //在消失的时候 或被原样扔到队列里面去
    //重复利用时 需要显示新的内容

    //取出section对应的group模型
    XLCarGroupModel *model = [_groupModelsArray objectAtIndex:indexPath.section];

    //取出row对应的car模型
    XLCarModel *carModel = [model.cars objectAtIndex:indexPath.row];

    //获得图片
    cell.imageView.image = [UIImage imageNamed:carModel.icon];

    //获得名字
    cell.textLabel.text = carModel.name;

    //设置默认的accessoryType
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    //自定义一个accessoryView
    cell.accessoryView = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 60, 40)];

    return cell;
}

2.使用代码自定义cell,在自定义cell里面封装创建

//自己创建一个类方法
+(XLCarCell *)cellWithModel:(XLCarModel *)model TableView:(UITableView *)tableView{
    XLCarCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellID"];
    if (cell == nil) {
        cell = [[XLCarCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cellID"];
    }
    cell.model = model;
    
    return cell;
}

//手动或者系统自动生成cell都会调用initWithStyle方法
//界面布局就在这里面写
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        
        //注意:执行这个代码的时候 cell只有默认尺寸 高度是44 宽度是tableView的宽度
        //在layoutSubview里面计算
        
        //图片
        self.iconImageView = [UIImageView new];

        //文本
        self.nameLabel = [UILabel new];
        _nameLabel.textAlignment = NSTextAlignmentLeft;
        
        [self.contentView addSubview:_iconImageView];
        [self.contentView addSubview:_nameLabel];
        
    }
    return  self;
}

-(void)layoutSubviews{
    [super layoutSubviews];
    
    //重新设置坐标
    
    //使用masonry设置控件的约束
    [_iconImageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.leading.top.mas_equalTo(10);
        make.bottom.mas_equalTo(-10);
        make.width.equalTo(self.iconImageView.mas_height);
    }];
    
    [_nameLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.leading.equalTo(self.iconImageView.mas_trailing).offset(20);
        make.centerY.equalTo(self.iconImageView);
        make.trailing.equalTo(self.mas_trailing).offset(-20);
        make.height.equalTo(self);
    }];
    
//    _iconImageView.frame = CGRectMake(10, 10, 60, self.viewForLastBaselineLayout.frame.size.height-20);
//
//    _nameLabel.frame = CGRectMake(CGRectGetMaxX(_iconImageView.frame)+20, 0, self.frame.size.width-CGRectGetMaxX(_iconImageView.frame)-10, self.frame.size.height);
}

//重写model的set方法
-(void)setModel:(XLCarModel *)model{
    
    _model = model;
    
    //显示数据
    _iconImageView.image = [UIImage imageNamed:_model.icon];
    _nameLabel.text = _model.name;
}

3.用xib自定义cell并封装cell的操作

创建一个User Interface的Empty文件,拖动一个TableViewCell进去,并将其与我们创建的类关联,一定要给cell设置Identifier

-(void)setModel:(XLCarModel *)model{
    _model = model;
    
    //数据来了 给控件赋值
    _iconImageView.image = [UIImage imageNamed:model.icon];
    
    _nameLabel.text = model.name;
}

+(XLCarXibCell *)cellWithModel:(XLCarModel *)model TableView:(UITableView *)tableView{
    XLCarXibCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellID"];
    //如果没有重复利用的就自己创建
    if (!cell) {
        //使用loadNib方法加载xib里面的cell
        cell = [[[NSBundle mainBundle] loadNibNamed:@"XLCarXibCell" owner:self options:nil] firstObject];
    }
    
    cell.model = model;
    
    return cell;
}

四.运行结果

运行截图

工程文件的链接
链接:https://pan.baidu.com/s/1HnALqHfo-dfEAgFjmcpX2Q 密码:road

上一篇下一篇

猜你喜欢

热点阅读