搜索
您的当前位置:首页正文

自定义 tableView 的 cell

来源:二三娱乐

- 自定义等高的 cell

一、storyboard 自定义 cell

1.创建一个继承自 UITableViewCell 的子类,比如 YJWGoodsCell


2.在 storyboard 中:
  • 设置 cell 的重用标识


  • 设置 cell 的 class 为 YJWGoodsCell


  • 往 cell 里面增加需要用到的子控件

3.在控制器中:

  • 通过懒加载加载数据
-(NSArray *)goodsArray{

    if (_goodsArray == nil) {
        NSString *path = [[NSBundle mainBundle]pathForResource:@"deals" ofType:@".plist"];
        NSArray *dicArray = [NSArray arrayWithContentsOfFile:path];
        
        NSMutableArray *array = [[NSMutableArray alloc]init];
        for (NSDictionary *dic in dicArray) {
            YJWGoodsModel *goods = [YJWGoodsModel goodWithDict:dic];
            [array addObject:goods];
        }
        _goodsArray = array;
    }
    
    return _goodsArray;
}
  • 利用重用标识符找到 cell
  • 给 cell 传递模型数据
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        static NSString *reUseId = @"cell";
        YJWGoodsCell *cell = [tableView dequeueReusableCellWithIdentifier:reUseId];
    
        cell.goods = self.goodsArray[indexPath.row];
    
        return cell;
}

4.在 YJWGoodsModel 中:

  • 设置模型,并提供一个通过字典创建模型的方法
/** title   */
@property(nonatomic,strong) NSString *title;
/** icon   */
@property(nonatomic,strong) NSString *icon;
/** price   */
@property(nonatomic,strong) NSString *price;
/** count   */
@property(nonatomic,strong) NSString *buyCount;
+(instancetype)goodWithDict:(NSDictionary *)dict;
  • 在模型中的具体实现
#import "YJWGoodsModel.h"

@implementation YJWGoodsModel

+(instancetype)goodWithDict:(NSDictionary *)dict
{    
    YJWGoodsModel *good = [[self alloc]init];
    [good setValuesForKeysWithDictionary:dict];
    
    return good;
}

@end

5.在 YJWGoodsCell 中:

  • 将 storyboard 中的子控件连线到类扩展中
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UILabel *title;
@property (weak, nonatomic) IBOutlet UILabel *price;
@property (weak, nonatomic) IBOutlet UILabel *count;
  • 需要提供一个模型属性,重写模型的 set 方法,在这个方法中设置模型数据到子控件上
@property(strong,nonatomic)YJWGoodsModel *goods;
-(void)setGoods:(YJWGoodsModel *)goods{
    _goods = goods;
    
    self.iconView.image = [UIImage imageNamed:goods.icon];
    self.title.text = goods.title;
    self.price.text = [NSString stringWithFormat:@"¥ %@",goods.price];
    self.count.text = [NSString stringWithFormat:@"%@人已购买",goods.buyCount];
}

二、xib 自定义 cell

1.创建一个继承自 UITableViewCell 的子类,比如 YJWGoodsCell
2.创建一个 xib 文件(文件名建议跟 cell 的类名一样),比如 YJWGoodsCell.xib

  • 拖拽一个 UITableViewCell 出来
  • 修改 cell 的 class 为 YJWGoodsCell
  • 设置 cell 的重用标识符


  • 往 cell 中添加需要用到的子控件

3.在控制器中

  • 利用 registerNib... 方法注册 xib 文件
UINib *nib = [UINib nibWithNibName:@"YJWGoodsCell" bundle:nil];
    [self.myTableView registerNib:nib forCellReuseIdentifier:@"YJWcell"];
  • 利用重用标识符找到 cell
  • 给 cell 传递模型数据
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        static NSString *reUseId = @"YJWcell";

        YJWGoodsCell *cell = [tableView dequeueReusableCellWithIdentifier:reUseId];      
        cell.goods = self.goodsArray[indexPath.row]; 
   
        return cell;
}

如果没有注册 xib 文件,就需要手动去加载 xib 文件:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        static NSString *reUseId = @"YJWcell";
        YJWGoodsCell *cell = [tableView dequeueReusableCellWithIdentifier:reUseId];

        if (cell == nil) {
        cell = [[NSBundle mainBundle]loadNibNamed:@"YJWGoodsCell" owner:nil options:nil][0];
    }
        cell.goods = self.goodsArray[indexPath.row];

        return cell;
}

4.在 YJWGoodsCell 中

  • 将 xib 中的子控件连线到类扩展中
  • 需要提供一个模型属性,重写模型的 set 方法,在这个方法中设置模型数据到子控件上
  • 也可以将创建获得 cell 的代码封装起来

三、1️⃣代码自定义 cell

1.创建一个继承自 UITableViewCell 的子类,比如 YJWGoodsCell

  • 在 initWithStyle:reuseIdentifier:方法中:
    • 添加子控件
    • 设置子控件的初始化属性(比如文字的颜色、字体)
  • 在 layoutSubviews 方法中设置子控件的 frame
    • 这个方法专门用来布局子控件,一般在这里设置子控件的 frame,当控件本身的尺寸发生改变的时候,系统会自动调用这个方法
  • 需要提供一个模型属性,重写模型的 set 方法,在这个方法中设置模型数据到子控件

2.在控制器中

  • 利用 registerClass... 方法注册 YJWGoodsCell 类
  • 利用重用标识符找到 cell (如果没有注册类,就需要手动创建cell)
  • 给 cell 传递模型数据

2️⃣代码自定义 cell

1.创建一个继承自 UITableViewCell 的子类,比如 YJWGoodsCell

  • 在 initWithStyle:reuseIdentifier:方法中:
    • 添加子控件
    • 添加子控件约束(建议使用 masonry)
    • 设置子控件的初始化属性(比如文字的颜色、字体)
  • 需要提供一个模型属性,重写模型的 set 方法,在这个方法中设置模型数据到子控件

2.在控制器中

  • 利用 registerClass... 方法注册 YJWGoodsCell 类
  • 利用重用标识符找到 cell (如果没有注册类,就需要手动创建cell)
  • 给 cell 传递模型数据

- 自定义非等高 cell

一、xib 自定义cell(重要)

  • 在模型中增加一个 cellHeight 属性,用来存放对应 cell 的高度
  • 在 cell 的模型属性 set 方法中调用 [self layoutIfNeeded] 方法强制布局,然后计算出 cellHeight 属性值
  • 在控制器中实现 -tableView: estimatedHeightForRowAtIndexPath: 方法,返回一个估计高度,比如 200【调用此方法后,先执行 tableView:(UITableView *)tableView cellForRowAtIndexPath: 然后再执行 tableView:heightForRowAtIndexPath: 方法,否则执行顺序相反】
  • 在控制器中实现 tableView:heightForRowAtIndexPath: 方法,返回 cell 的真实高度(模型中的 cellHeight 属性)
  • 当 label 中的内容不止一行时,系统计算往往会有些布局上的瑕疵,此时在 cell 中实现如下方法,会有所改善:
-(void)awakeFromNib{
//设置 label 每一行文字的最大宽度
//为了保证计算出来的数值 跟 真正显示出来的效果一致
self.content.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20;
}

二、storyboard 定义 cell

和用 xib 自定义 cell 类似,内部各控件换个地方而已。

三、代码自定义 cell(frame)

四、代码自定义 cell(Autolayout)

与自定义等高 cell 极其相似。

Top