自定义等高 Cell

Posted ch520

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自定义等高 Cell相关的知识,希望对你有一定的参考价值。

1、介绍

  • 1.1 代码自定义 cell(使用 frame)

    • 创建一个继承自 UITableViewCell 的子类,比如 BookCell1。
      • 在 initWithStyle:reuseIdentifier: 方法中。
        • 添加子控件。
        • 设置子控件的初始化属性(比如文字颜色、字体)。
      • 在 layoutSubviews 方法中设置子控件的 frame。
      • 需要提供一个模型属性,重写模型的 set 方法,在这个方法中设置模型数据到子控件。
    • 在控制器中
      • 利用 registerClass... 方法注册 BookCell1 类。
      • 利用重用标识找到 cell(如果没有注册类,就需要手动创建 cell)。
      • 给 cell 传递模型数据。
      • 也可以将创建获得 cell 的代码封装起来(比如 cellWithTableView: 方法)。
  • 1.2 代码自定义 cell(使用 autolayout)

    • 创建一个继承自 UITableViewCell 的子类,比如 BookCell1。
      • 在 initWithStyle:reuseIdentifier: 方法中。
        • 添加子控件。
        • 添加子控件的约束(建议使用 Masonry)。
        • 设置子控件的初始化属性(比如文字颜色、字体)。
        • 需要提供一个模型属性,重写模型的 set 方法,在这个方法中设置模型数据到子控件。
    • 在控制器中
      • 利用 registerClass... 方法注册 BookCell1 类。
      • 利用重用标识找到 cell(如果没有注册类,就需要手动创建 cell)。
      • 给 cell 传递模型数据。
      • 也可以将创建获得 cell 的代码封装起来(比如 cellWithTableView: 方法)。

2、代码创建 cell - frame

  • 2.1 BookCell1.h

@class BookModel;

@interface BookCell1 : UITableViewCell

// 定义 Cell 的数据模型
@property (nonatomic, retain)BookModel *book;

@end
  • 2.2 BookCell1.m

#import "BookCell1.h"
#import "BookModel.h"

@interface BookCell1()

// 创建自定义 Cell 视图包含的内容
@property(nonatomic, retain)UIImageView *iconView;
@property(nonatomic, retain)UILabel *titleLabel;
@property(nonatomic, retain)UILabel *detailLabel;
@property(nonatomic, retain)UILabel *priceLabel;

@end

@implementation BookCell1

// 重写初 Cell 始化方法,创建自定义 Cell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {

    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {

        // 创建子视图
        // 创建 iconView 视图,并添加到自定义 Cell 上
        self.iconView = [[UIImageView alloc] init];
        self.iconView.layer.borderColor = [[UIColor greenColor] CGColor];
        self.iconView.layer.borderWidth = 2;
        [self.contentView addSubview:self.iconView];

        // 创建 titleLabel 视图
        self.titleLabel = [[UILabel alloc] init];
        self.titleLabel.font = [UIFont boldSystemFontOfSize:14];
        self.titleLabel.textColor = [UIColor redColor];
        [self.contentView addSubview:self.titleLabel];

        // 创建 detailLabel 视图
        self.detailLabel = [[UILabel alloc] init];
        self.detailLabel.font = [UIFont systemFontOfSize:12];
        [self.contentView addSubview:self.detailLabel];

        // 创建 priceLabel 视图
        self.priceLabel = [[UILabel alloc] init];
        self.priceLabel.font = [UIFont systemFontOfSize:12];
        [self.contentView addSubview:self.priceLabel];
    }
    return self;
}

// 布局子视图
- (void)layoutSubviews {
    [super layoutSubviews];

    // 布局子视图
    self.iconView.frame = CGRectMake(10, 10, 60, 60);
    self.titleLabel.frame = CGRectMake(90, 5, 200, 25);
    self.detailLabel.frame = CGRectMake(90, 30, 200, 25);
    self.priceLabel.frame = CGRectMake(90, 55, 200, 25);
}

// 设置显示的数据
- (void)setBook:(BookModel *)book {

    _book = book;

    // 设置数据,设置 cell 视图上显示的内容 内容
    self.iconView.image = [UIImage imageNamed:book.icon];
    self.titleLabel.text = book.title;
    self.detailLabel.text = book.detail;
    self.priceLabel.text = book.price;
}

@end
  • 2.3 ViewController.m

// 使用自定义 Cell 创建,UITableViewDataSource 协议方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    // 使用自定义的 Cell 定义
    BookCell1 *cell = [tableView dequeueReusableCellWithIdentifier:@"testIdentifier"];

    if (cell == nil) {
        // 使用自定义的 Cell 创建
        cell = [[BookCell1 alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"testIdentifier"];
    }
    BookModel *bookModel = [self.myDataArray objectAtIndex:indexPath.row];
    cell.book = bookModel;

    return cell;
}

3、代码注册 cell - frame

  • 在 tableView 创建时,从 ios7 开始多了一种创建 cell 的方式(注册),让 tableView 注册一种 cell,需要设置复用标志。
  • 用注册方式创建 cell,如果 tableView 已经注册了某一种 cell,从复用队列里查找,如果找不到,
  • 系统会自动通过注册的 cell 类来创建 cell 对象。
  • 3.1 自定义 Cell 部分同上。

  • BookCell1.h
  • BookCell1.m
  • 3.2 ViewController.m

// 注册 cell
[myTableView registerClass:[BookCell1 class] forCellReuseIdentifier:@"testIdentifier"];

// 使用注册的 Cell 创建,UITableViewDataSource 协议方法
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    BookCell1 *cell = [tableView dequeueReusableCellWithIdentifier:@"testIdentifier" forIndexPath:indexPath];                   
    BookModel *bookModel = [self.myDataArray objectAtIndex:indexPath.row];

    cell.book = bookModel;

    return cell;
}

4、代码创建 cell - autolayout

@interface XMGDeal : NSObject

@property (strong, nonatomic) NSString *buyCount;
@property (strong, nonatomic) NSString *price;
@property (strong, nonatomic) NSString *title;
@property (strong, nonatomic) NSString *icon;

+ (instancetype)dealWithDict:(NSDictionary *)dict;

@end
  • 4.2 XMGDeal.m

@implementation XMGDeal

+ (instancetype)dealWithDict:(NSDictionary *)dict {

    XMGDeal *deal = [[self alloc] init];

    // KVC - Key Value Coding
    [deal setValuesForKeysWithDictionary:dict];

    return deal;
}

@end
  • 4.3 XMGDealCell.h

@class XMGDeal;

@interface XMGDealCell : UITableViewCell

/** 模型数据 */
@property (nonatomic, strong) XMGDeal *deal;

+ (instancetype)cellWithTableView:(UITableView *)tableView;

@end
  • 4.4 XMGDealCell.m

#define MAS_SHORTHAND
#define MAS_SHORTHAND_GLOBALS

#import "Masonry.h"

@interface XMGDealCell()

@property (weak, nonatomic) UIImageView *iconView;
@property (weak, nonatomic) UILabel *titleLabel;
@property (weak, nonatomic) UILabel *priceLabel;
@property (weak, nonatomic) UILabel *buyCountLabel;

@end

@implementation XMGDealCell

+ (instancetype)cellWithTableView:(UITableView *)tableView {

    static NSString *ID = @"deal";

    // 创建cell
    XMGDealCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];

    if (cell == nil) {
        cell = [[XMGDealCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
    }
    return cell;
}

// 1.在 initWithStyle:reuseIdentifier: 方法中添加子控件
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {

        UIImageView *iconView = [[UIImageView alloc] init];
        [self.contentView addSubview:iconView];
        self.iconView = iconView;

        UILabel *titleLabel = [[UILabel alloc] init];
        [self.contentView addSubview:titleLabel];
        self.titleLabel = titleLabel;

        UILabel *priceLabel = [[UILabel alloc] init];
        priceLabel.textColor = [UIColor orangeColor];
        [self.contentView addSubview:priceLabel];
        self.priceLabel = priceLabel;

        UILabel *buyCountLabel = [[UILabel alloc] init];
        buyCountLabel.textAlignment = NSTextAlignmentRight;
        buyCountLabel.font = [UIFont systemFontOfSize:14];
        buyCountLabel.textColor = [UIColor lightGrayColor];
        [self.contentView addSubview:buyCountLabel];
        self.buyCountLabel = buyCountLabel;
    }
    return self;
}

// 2.在 layoutSubviews 方法中设置子控件的 约束
- (void)layoutSubviews {

    [super layoutSubviews];

    CGFloat margin = 10;

    [self.iconView makeConstraints:^(MASConstraintMaker *make) {
        make.width.equalTo(100);
        make.left.top.offset(margin);
        make.bottom.offset(-margin);
    }];

    [self.titleLabel makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.iconView);
        make.left.equalTo(self.iconView.right).offset(margin);
        make.right.offset(-margin);
    }];

    [self.priceLabel makeConstraints:^(MASConstraintMaker *make) {
        make.left.equalTo(self.titleLabel);
        make.bottom.equalTo(self.iconView);
        make.width.equalTo(70);
    }];

    [self.buyCountLabel makeConstraints:^(MASConstraintMaker *make) {
        make.bottom.equalTo(self.priceLabel);
        make.right.equalTo(self.titleLabel);
        make.left.equalTo(self.priceLabel.right).offset(margin);
    }];
}

// 3.重写模型的 set 方法
- (void)setDeal:(XMGDeal *)deal {

    _deal = deal;

    // 设置数据
    self.iconView.image = [UIImage imageNamed:deal.icon];
    self.titleLabel.text = deal.title;
    self.priceLabel.text = [NSString stringWithFormat:@"¥%@", deal.price];
    self.buyCountLabel.text = [NSString stringWithFormat:@"%@人已购买", deal.buyCount];
}

@end
  • 4.5 XMGDealsViewController.m

@interface XMGDealsViewController ()

/** 所有的团购数据 */
@property (nonatomic, strong) NSArray *deals;

@end

@implementation XMGDealsViewController

- (NSArray *)deals {

    if (_deals == nil) {

        // 加载plist中的字典数组
        NSString *path = [[NSBundle mainBundle] pathForResource:@"deals.plist" ofType:nil];
        NSArray *dictArray = [NSArray arrayWithContentsOfFile:path];

        // 字典数组 -> 模型数组
        NSMutableArray *dealArray = [NSMutableArray array];
        for (NSDictionary *dict in dictArray) {
            XMGDeal *deal = [XMGDeal dealWithDict:dict];
            [dealArray addObject:deal];
        }

        _deals = dealArray;
    }
    return _deals;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    //    [self.tableView registerClass:[XMGDealCell class] forCellReuseIdentifier:@"deal"];
}

#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return self.deals.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    //创建cell
    XMGDealCell *cell = [XMGDealCell cellWithTableView:tableView];

    // 取出模型数据
    cell.deal = self.deals[indexPath.row];

    return cell;
}

@end

以上是关于自定义等高 Cell的主要内容,如果未能解决你的问题,请参考以下文章

自定义等高 Cell

源码-020501-自定义非等高cell-storyboard

源码-0203-06-自定义非等高cell-xib

iOS边练边学--自定义非等高的cell

div+css:两个div并排等高 (table-cell)

IOS 通过 代码 自定义cell(Cell的高度不一致)(优化性能)