tableView简单认识以及性能优化

来源:互联网 发布:济南淘宝代运营公司 编辑:程序博客网 时间:2024/06/05 01:56

    • 如何让tableView展示数据
    • tableView的常见设置
    • tableViewCell的常见设置
    • tableView常见的代理方法
    • cell的循环利用
  • mutiSectionsTableView
    • tableView如何展示数据
    • 保持tableView数据独立
      • 新需求再添加一组数据时候需要修改全部数据源方法
      • 思路将所有需要修改的数据集中到一处
      • 分析模型的创建
  • 单组数据展示
  • 缺少一张图片系统自带的cell样式
    • tableView常见属性
    • cell常见属性
    • 常见代理易错属性
    • 性能优化
      • 思考cell进入屏幕创建离开屏幕销毁频繁调用极耗性能如何解决
    • cell的循环利用
      • 方法1传统方法
      • 方法2注册
      • 方法3storyboard
    • sectionIndex索引条
      • 复习多组数据的展示
      • 复杂plist文件解析
      • 宏定义
      • 核心代码
      • UITableViewController
    • cellWithTableView
      • cell获取封装
      • 数据覆盖封装
      • 封装后创建cell的数据源方法只需要3步

如何让tableView展示数据

  • 设置数据源对象
/*也可以直接在storyboard中拖线,让tableView控件的delegate指             向ViewController*/self.tableView.dataSource = self;
  • 数据源对象要遵守协议
@interface ViewController () <UITableViewDataSource>@end
  • 实现数据源方法(向tableView中添加数据)
// 多少组数据- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;// 每一组有多少行数据- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;// 每一行显示什么内容- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;// 每一组的头部显示内容- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;// 每一组的尾部显示内容- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section

tableView的常见设置

// 设置每一行cell的高度self.tableView.rowHeight = 100;// 设置每一组头部的高度self.tableView.sectionHeaderHeight = 50;// 设置每一组尾部的高度self.tableView.sectionFooterHeight = 50;// 设置分割线颜色self.tableView.separatorColor = [UIColor redColor];// 设置分割线样式self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;// 设置表头控件self.tableView.tableHeaderView = [[UISwitch alloc] init];// 设置表尾控件self.tableView.tableFooterView = [UIButton buttonWithType:UIButtonTypeContactAdd];// 设置右边索引文字的颜色self.tableView.sectionIndexColor = [UIColor redColor];// 设置右边索引文字的背景色self.tableView.sectionIndexBackgroundColor = [UIColor blackColor];

tableViewCell的常见设置

// 设置右边的指示样式(>形状图标,对勾图标,或者是Information图标)cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;// 设置右边的指示控件cell.accessoryView = [[UISwitch alloc] init];// 设置cell的选中样式cell.selectionStyle = UITableViewCellSelectionStyleNone;// backgroundView优先级 > backgroundColor// 设置背景色cell.backgroundColor = [UIColor redColor];// 设置背景viewUIView *bg = [[UIView alloc] init];bg.backgroundColor = [UIColor blueColor];cell.backgroundView = bg;// 设置选中的背景viewUIView *selectedBg = [[UIView alloc] init];selectedBg.backgroundColor = [UIColor purpleColor];cell.selectedBackgroundView = selectedBg;

tableView常见的代理方法

// 当点击cell的时候就会调用,选中当前的cell(cell选中样式为None的时候也会调用)- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath// 取消选中cell时调用的方法- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath// 返回对应的indexPath的cell的高度- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath// 返回第section组的组尾高度- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section// 返回第section组的组头高度- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section// 返回section的组尾view(优先级高于数据源方法)- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section// 返回section的组头view(优先级高于数据源方法)- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section

cell的循环利用

  • 传统的写法
/** *  每当有一个cell要进入视野范围内,就会调用一次 */- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    static NSString *ID = @"wine";    // 1.先去缓存池中查找可循环利用的cell    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];    // 2.如果缓存池中没有可循环利用的cell    if (!cell) {        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];    }    // 3.设置数据    cell.textLabel.text = [NSString stringWithFormat:@"%zd行的数据", indexPath.row];    return cell;}
  • 新的写法(注册cell)-01
NSString *ID = @"wine";- (void)viewDidLoad {    [super viewDidLoad];    // 注册某个重用标识 对应的 Cell类型    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID];}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    // 1.先去缓存池中查找可循环利用的cell    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];    // 2.设置数据    cell.textLabel.text = [NSString stringWithFormat:@"%zd行的数据", indexPath.row];    return cell;}
  • 新的写法(注册cell)-02
BOOL reged = NO;- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    static NSString *ID = @"wine";    if (reged == NO)    {        // 注册某个重用标识 对应的 Cell类型        [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID];        reged = YES;    }    // 1.先去缓存池中查找可循环利用的cell    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];    // 2.设置数据    cell.textLabel.text = [NSString stringWithFormat:@"%zd行的数据", indexPath.row];    return cell;}
  • storyboard - 03
// 首先在storyboard中设置cell的identifier为@"wine",然后执行下面代码即可- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    static NSString *ID = @"wine";    // 1.先去缓存池中查找可循环利用的cell    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];    // 2.设置数据    cell.textLabel.text = [NSString stringWithFormat:@"%zd行的数据", indexPath.row];    return cell;}

mutiSectionsTableView

tableView如何展示数据?

  • 通过数据源

@property (nonatomic, assign) id <UITableViewDataSource> dataSource;

  • 设置数据源

    // 1.在viewDidLoad方法中设置tableView.dataSource = self;// 2.在storyboard中拖线
  • 遵守数据源协议<UITableViewDataSource>
  • 实现数据源方法

保持tableView数据独立

新需求再添加一组数据时候,需要修改全部数据源方法!

思路:将所有需要修改的数据集中到一处

  • 创建一个新的数组属性

@property (nonatomic, strong) NSArray *groups; /**< group模型数组 */

  • 通过懒加载为数组赋值
// 懒加载- (NSArray *)groups{    if (!_groups) {        XMGGroup *g0 = [[XMGGroup alloc] init];        g0.header = @"adc";        g0.footer = @"物理输出脆皮";        g0.heros = @[[XMGHero heroWithName:@"艾希" Icon:@"hanbing"],                     [XMGHero heroWithName:@"崔斯特娜" Icon:@"xiaopao"],                     [XMGHero heroWithName:@"金克斯" Icon:@"金克斯"]];        XMGGroup *g1 = [[XMGGroup alloc] init];        g1.header = @"apc";        g1.footer = @"法术输出脆皮";        g1.heros = @[[XMGHero heroWithName:@"阿狸" Icon:@"ali"],                     [XMGHero heroWithName:@"火男" Icon:@"huonan"],                     [XMGHero heroWithName:@"球女" Icon:@"qiunv"]];        XMGGroup *g2 = [[XMGGroup alloc] init];        g2.header = @"上单";        g2.footer = @"上单爸爸不好惹";        g2.heros = @[[XMGHero heroWithName:@"大保健" Icon:@"dabaojian"],                     ];        _groups = @[g0, g1, g2];    }    return _groups;}
  • 这样再添加数据,只需要对懒加载中的数据进行操作即可

  • 实际开发中,所用的数据也是从服务器拿到后展示出来的

分析模型的创建

  • 组头
  • 组尾
  • cell上的内容(数组)
    • 每个cell上的内容分为name和icon
    • 创建hero模型

单组数据展示

  • 数据源方法:返回多少组可以不实现
// Default is 1 if not implemented 如果不实现,默认就是1//- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView//{//    return 1;//}
  • cell上自带3个展示信息的子控件
    cell.textLabel.text = car.name;    // 系统自带的cell的非value2样式并且有数据才展示    cell.imageView.image = [UIImage imageNamed:car.icon];    // 系统自带cell的非default样式并且有数据时候才展示    cell.detailTextLabel.text = car.money;
  • 系统自带的cell的四个样式

缺少一张图片(系统自带的cell样式)

  • 复习简单plist文件解析
// 1.拿到plist的文件路径    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"cars.plist" ofType:nil];    // 2.创建对应的JSON数据    NSArray *dicts = [NSArray arrayWithContentsOfFile:filePath];    // 3.JSON->Model    NSMutableArray *arrayM = [NSMutableArray arrayWithCapacity:dicts.count];    for (NSDictionary *dict in dicts) {        // 3.1 Dict->Model        XMGCar *obj = [XMGCar carWithDict:dict];        [arrayM addObject:obj];    }
  • Dict->Model
+ (instancetype)carWithDict:(NSDictionary *)dict{    XMGCar *car = [[self alloc] init];//    car.name = dict[@"name"];//    car.icon = dict[@"icon"];//    car.money = dict[@"money"];    // kvc 相当于上面3行    [car setValuesForKeysWithDictionary:dict];    return car;}

tableView常见属性

// 设置tableView的属性- (void)setupTableViewProPerty{    // tableView的行高如果不修改,默认是44    self.tableView.rowHeight = 88;    // 设置tableView组头,组尾的统一高度    self.tableView.sectionHeaderHeight = 44;    self.tableView.sectionFooterHeight = 66;    // 表头/尾 视图    self.tableView.tableHeaderView = [[UISwitch alloc] init];    self.tableView.tableFooterView = [UIButton buttonWithType:UIButtonTypeContactAdd];    // 分割线颜色 设置成[UIColor clearColor]代表去掉分割线    self.tableView.separatorColor = [UIColor redColor];    // 设置分割线样式    self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;}

cell常见属性

#pragma mark - cell常见属性// 方法抽取的技巧就是将变量写成参数传进来// 相同业务逻辑的的代码尽量抽取成方法- (void)setupCellProperty:(UITableViewCell *)cell row:(NSInteger)row{    // cell的常见属性    // 设置cell的背景颜色    cell.backgroundColor = (row % 2)? [UIColor yellowColor]: [UIColor orangeColor];    // 设置cell的背景视图,并且backgroundView的优先级比backgroundColor高一些    //    UIView *cellBg = [[UIView alloc] init];    //    cellBg.backgroundColor = [UIColor grayColor];    //    cell.backgroundView = cellBg;    /*     UITableViewCellAccessoryNone,                   // don't show any accessory view     UITableViewCellAccessoryDisclosureIndicator,    //  尖尖 regular chevron. doesn't track     UITableViewCellAccessoryDetailDisclosureButton, // 圈i + 尖尖info button w/ chevron. tracks     UITableViewCellAccessoryCheckmark,              // 小对勾 checkmark. doesn't track     UITableViewCellAccessoryDetailButton NS_ENUM_AVAILABLE_IOS(7_0) // 圈i info button. tracks     */    // cell的辅助视图样式    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;    // cell的辅助视图,作用优先级高于accessoryType    cell.accessoryView = [[UISwitch alloc] init];    /*     UITableViewCellSelectionStyleNone, // 设置没有选中样式     UITableViewCellSelectionStyleBlue, // 在iOS6之前,选中背景色变蓝,iOS7之后,和gray相同     UITableViewCellSelectionStyleGray, // 默认样式     UITableViewCellSelectionStyleDefault NS_ENUM_AVAILABLE_IOS(7_0) // 默认样式     */    cell.selectionStyle = UITableViewCellSelectionStyleGray;    // 在UITableViewCellSelectionStyleNone样式中,设置selectedBackgroundView是无效的    /*     在     UITableViewCellSelectionStyleBlue, // 在iOS6之前,选中背景色变蓝,iOS7之后,和gray相同     UITableViewCellSelectionStyleGray, // 默认样式     UITableViewCellSelectionStyleDefault NS_ENUM_AVAILABLE_IOS(7_0) // 默认样式     3种样式下,selectedBackgroundView他的优先级高于selectionStyle     */    UIView *cellsBg = [[UIView alloc] init];    cellsBg.backgroundColor = [UIColor redColor];    cell.selectedBackgroundView = cellsBg;    /*            contentView = 0x7f96fb553470:     cell.textLabel.superview = 0x7f96fb553470     ==0x7f96fb553470     ==0x7f96fb553470     */    // cell上面的子控件不是直接添加在cell上,而是添加到contentView上    NSLog(@"contentView = %p: cell.textLabel.superview = %p==%p==%p", cell.contentView, cell.textLabel.superview, cell.imageView.superview, cell.detailTextLabel.superview);}
  • 注意:cell上面的子控件要添加到cell.contentView上

常见代理/易错属性

  • 前两者易错
// 选中某一行时候调用- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{    NSLog(@"%s, row = %ld", __FUNCTION__, indexPath.row);}// 取消选中某一行时候调用- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{    NSLog(@"%s, row = %ld", __FUNCTION__, indexPath.row);}// 根据indexPath返回对应的高度- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{    if (indexPath.row == 0) {        return 222;    }    return 88;}
  • 分割线样式的枚举容易写错
#warning 在设置分割线样式为None的时候如果无效,先看你是否搞混了下列2个枚举    /*    UITableViewCellSeparatorStyleNone    UITableViewCellSelectionStyleNone     */     self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;

性能优化

思考:cell进入屏幕创建,离开屏幕销毁;频繁调用极耗性能如何解决?

  • 利用tableView的缓存池,存放离开屏幕的cell
  • 当cell进入屏幕后,先取缓存池若没有再新建
  • 这样就可以只创建n+1个cell来展示所有数据
    –n表示屏幕上显示cell的最大数量

cell的循环利用

  • 确定重用标识
  • 根据标识从缓存池中取
    • 封装若没有根据注册创建,拿到return,nil继续
    • nil后继续查看storyboard中是否有带重用标识的cell
  • 若返回nil则手动创建
  • 覆盖cell上的数据
  • 返回cell

方法1:传统方法

/* 0.先确定cell的重用标识 1.查看缓存池中是否有带重用标识的cell 2.如果没有才创建带重用标识的cell 3.覆盖cell上面的数据 说明:当cell离开屏幕的时候,就会放到tableView的缓存池中,这时候缓存池才有数据 */// 3.返回每行内容:// 该方法,只有当cell显示在屏幕上的时候才会调用,是一种懒加载的思想- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    // 3.0 先确定cell的重用标识:命名规范:数据的模型+ID    static NSString *ID = @"carID"; // static修饰局部变量,局部变量只会分配一次内存地址    // 3.1 查看缓存池中是否有带重用标识的cell    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];    // 3.2 如果没有才创建带重用标识的cell    if (!cell) {        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID];    }    // 3.3 覆盖cell上的数据    XMGCar *car = self.cars[indexPath.row];    cell.textLabel.text = [NSString...    // 3.4返回cell    return cell;}

方法2:注册

/* 另一中性能优化的写法: 0.先确定cell的重用标识 1.注册带重用标识的cell 2.从缓存池中取是否有带重用标识的cell(如果没有,系统会根据注册自动创建一个相应的cell返回给我们) 3.覆盖cell上面的数据 说明:当cell离开屏幕的时候,就会放到tableView的缓存池中,这时候缓存池才有数据 */// 3.返回每行内容:// 该方法,只有当cell显示在屏幕上的时候才会调用,是一种懒加载的思想- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    // 3.0 先确定cell的重用标识:命名规范:数据的模型+ID    static NSString *ID = @"carID"; // static修饰局部变量,局部变量只会分配一次内存地址    static BOOL isReged = NO;    // 3.1 先注册带ID的cell    if (isReged == NO) {#warning registerCell需要注意的3点,面试可能会问到        // 改方法是伴随着UICollectionView出现的,也就是iOS6出现的        // 采用注册创建出来的cell,默认是Default样式,所以一般注册大部分都用在自定义cell的时候        // 需要注意的是 [tableView registerNib:<#(UINib *)#> forCellReuseIdentifier:<#(NSString *)#>] 是iOS5出现的        [tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID];        isReged = YES;        NSLog(@"registerClassregisterClassregisterClassregisterClass");    }    // 3.2 查看缓存池中是否有带重用标识的cell    // 缓存池方法中封装了,如果缓存池中没有,就根据注册创建新的cell,然后返回给我们一个带ID的cell    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];    // 3.3 覆盖cell上的数据    XMGCar *car = self.cars[indexPath.row];    cell.textLabel.text = [NSString...    // 3.4返回cell    return cell;}

方法3:storyboard

/*  另一中性能优化的写法(storyboard): 0.先确定cell的重用标识 1.将storyboard中的tableView中的cell的重用标志赋值 2.从缓存池中取是否有带重用标识的cell    (2.1 如果没有,系统会根据注册自动创建一个相应的cell返回给我们;    2.2 如果也没有注册过,系统会根据storyboard中写好的带重用标志的cell来自动创建,然后返回) 3.覆盖cell上面的数据 说明:当cell离开屏幕的时候,就会放到tableView的缓存池中,这时候缓存池才有数据 */// 3.返回每行内容:// 该方法,只有当cell显示在屏幕上的时候才会调用,是一种懒加载的思想#warning 如果有注册,就不会触发storyboard的创建新cell的机制.只有没有注册过,并且storyboard中没有标记相应cell 的时候,dequeueReusableCellWithIdentifier才会返回nil- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{    // 3.0 先确定cell的重用标识:命名规范:数据的模型+ID    static NSString *ID = @"carID"; // static修饰局部变量,局部变量只会分配一次内存地址    // 3.1 查看缓存池中是否有带重用标识的cell    // 缓存池方法中封装了,如果缓存池中没有,就根据注册创建新的cell,然后返回给我们一个带ID的cell    // 后面还封装了一层,如果也没有注册呢,会根据storyboard中是否标记了在重用cell,来创建一个新的cell然后返回    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];    // 3.3 覆盖cell上的数据    XMGCar *car = self.cars[indexPath.row];    cell.textLabel.text = [N...    // 3.4返回cell    return cell;}

sectionIndex索引条

复习多组数据的展示

  • 设置数据源
  • 遵守协议(作用是方法提示)
  • 实现数据源方法

复杂plist文件解析

  • 字典就转模型(keys对应同名属性)
  • 层层递归
  • KVC的实现
    • 对应dictKeys的所有模型的属性set方法调用了一次
    • 复杂类型转换放在属性的set方法中

宏定义

#define XMGDictToModel_H(name)  + (instancetype)name##WithDict:(NSDictionary *)dict;#define XMGDictToModel_M(name)\+ (instancetype)name##WithDict:(NSDictionary *)dict\{\    NSObject *obj = [[self alloc] init];\    [obj setValuesForKeysWithDictionary:dict]; \    return obj; \}\#define dictToModel_H  + (instancetype)modelWithDict:(NSDictionary *)dict;#define dictToModel_M \+ (instancetype)modelWithDict:(NSDictionary *)dict \{ \NSObject *obj = [[self alloc] init]; \[obj setValuesForKeysWithDictionary:dict]; \return obj; \} \

核心代码

// 索引条方法- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView{//    NSMutableArray *arrayM = [NSMutableArray array];//    for (XMGCarGroup *carGroup in self.carGroups) {//        [arrayM addObject:carGroup.header];//    }//    return [arrayM copy];    // 此处kvc效果 == 上面4行代码    return [self.carGroups valueForKeyPath:@"header"];}//补充// 设置索引条的背景/文字 颜色    self.tableView.sectionIndexBackgroundColor = [UIColor yellowColor];    self.tableView.sectionIndexColor = [UIColor redColor];

UITableViewController

  • 继承在UIViewController
  • 遵守数据源和代理协议
  • 内部有个tableView
  • 代码相当于如此
@interface ViewController () <UITableViewDataSource, UITableViewDelegate>- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.    // 创建一个tableView    UITableView *tableView = [[UITableView alloc] init];    // 设置数据源和协议    tableView.dataSource = self;    tableView.delegate = self;    // 替换view为tableView    self.view = tableView;}

cellWithTableView:

cell获取封装

  • 将获取cell的代码全部copy到cell内部,发现需要用到变量tableView,传入即可

  • 传统封装

+ (instancetype)cellWithTableView:(UITableView *)tableView{    // 1.确定重用标识    static NSString *ID = @"carID";    // 2.从缓存池中取    XMGCarCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];    // 3.如果缓存池中没有,就自己创建    if (!cell) {        cell = [[XMGCarCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];    }    return cell;}
  • 注册封装
+ (instancetype)cellWithTableView:(UITableView *)tableView{    // 1.确定重用标识    static NSString *ID = @"carID";    static BOOL isReged = NO;    // 2.注册    if (isReged == NO) {        [tableView registerClass:self forCellReuseIdentifier:ID];        isReged = YES;    }    // 3.从缓存池中取    XMGCarCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];    return cell;}

数据覆盖封装

  • 为cell添加模型属性

@property (nonatomic, strong) XMGCar *car; /**< carModel */

  • 重写模型set方法完成内部赋值
- (void)setCar:(XMGCar *)car{    _car = car;    self.imageView.image = car.icon;    self.textLabel.text = car.name;}

封装后创建cell的数据源方法只需要3步

  • 获取cell
  • 覆盖数据
  • 返回cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {    // 3.1 获取cell    XMGCarCell *cell = [XMGCarCell cellWithTableView:tableView];    // 3.2 数据覆盖    // 这样写的好处就是,将cell覆盖数据一行完成,具体覆盖了哪些数据,进入cell内部看    XMGGroup *g = self.groups[indexPath.section];    XMGCar *car = g.cars[indexPath.row];    cell.car = car;    // 3.3.返回cell    return cell;}

0 0
原创粉丝点击