AZ_自定义不等高的cell

自定义不等高的cell


1.给模型增加frame数据(纯代码)

  • 让ViewController继承UITableViewController,移除storyboard中的ViewController,新建一个UITableViewController让其与ViewController建立关联。
    @interface ViewController:UITableViewController

  • 在ViewController.m文件中实现UITableView代理的这个方法,这个方法会返回cell的高度,所以需要在返回高度前计算出cell的高度。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    AZStatus *status=self.statuses[indexPath.row];

    return status.cellHeight;
}
  • 在status数据模型中计算出所有控件frame,只有模型数据知道哪些控件需要显示,这个方法会经常调用,考虑到性能对其进行判断,只有当第一次调用时才会计算。
- (CGFloat)cellHeight
{

    if (_cellHeight==0) {
        CGFloat margin=10;
        ...
        // 图片frame
        if (self.picture) {//有配图
            CGFloat picX=margin*3;
            CGFloat picY=CGRectGetMaxY(self.textFrame)+margin;
            CGFloat picWH=200;
            self.pictureFrame=CGRectMake(picX, picY, picWH, picWH);
            _cellHeight=CGRectGetMaxY(self.pictureFrame)+margin;
        }else{//无配图

            _cellHeight=CGRectGetMaxY(self.textFrame)+margin;
        }

    }

    return _cellHeight;
}
  • 添加控件
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self=[super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        ...

        //配图
        UIImageView *pictureView=[[UIImageView alloc]init];
        [self.contentView addSubview:pictureView];
        self.picture1View=pictureView;  

    }
  • 在AZStatusCell.h文件中引用模型
#import <UIKit/UIKit.h>
@class AZStatus;
@interface AZStatusCell : UITableViewCell

/*模型数据*/
@property(nonatomic,strong)AZStatus *status;

@end
  • 在模型的set方法中给控件注入数据,同时也可以确定frame,和在layoutSubViews中确定frame效果一致

-(void)setStatus:(AZStatus *)status
{
    _status=status;
    // 设置数据
    ...
    // 配图
    if (status.picture) {
        self.picture1View.hidden=NO;
        self.picture1View.image=[UIImage imageNamed:status.picture];
    }else{
        self.picture1View.hidden=YES;
    }

    //设置frame
    self.iconView.frame=status.iconFrame;
    self.nameLabel.frame=status.nameFrame;
    self.text_Label.frame=status.textFrame;
    self.vipView.frame=status.vipFrame;
    self.picture1View.frame=status.pictureFrame;

}

2.storyboard动态cell实现(iOS8以后)

  • 在stroyboard的动态cell中添加所有的子控件
    这里写图片描述

  • 将cell中所有的子控件和AZStatusCell.m文件中的属性建立好连线,并将图片的约束也建立好连线
    这里写图片描述

  • 在status模型的set方法中,通过图片高度的约束控制图片显示与隐藏,上方间隙的约束的调整来控制所有cell下方的间隙一致
-(void)setStatus:(AZStatus *)status
{
    _status=status;

    // 设置数据
    ...    
    // 配图
    if (status.picture) {
        self.picture1View.hidden=NO;
        self.picture1View.image=[UIImage imageNamed:status.picture];
        self.pictureTop.constant=10;
        self.pictureHeight.constant=100;

    }else{
        self.picture1View.hidden=YES;
        self.pictureHeight.constant=0;
        self.pictureTop.constant=0;
    }



}
  • 设置tableViewCell的真实行高和估算行高
    // self-sizing(iOS8以后,两个方法一起使用)
    // 设置tableView的高度为根据设定的约束自动计算
    self.tableView.rowHeight=UITableViewAutomaticDimension;

    // 设置tableView的估算高度
    self.tableView.estimatedRowHeight=44;

3.支持iOS8之前

  • 如果cell内部有自动换行的label,需要设置preferredMaxLayoutWidth属性
- (void)awakeFromNib
{
    // 手动设置文字的最大宽度(目的是:让label知道自己文字的最大宽度,进而能够计算出自己的frame)
    self.text_label.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20;
}
  • 设置tableView的cell估算高度
// 告诉tableView所有cell的估算高度(设置了估算高度,就可以减少tableView:heightForRowAtIndexPath:方法的调用次数)
self.tableView.estimatedRowHeight = 200;
  • 在代理方法中计算cell的高度
AZStatusCell *cell;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 创建一个临时的cell(cell的作用:根据模型数据布局所有的子控件,进而计算出cell的高度)
    if (!cell) {
        cell = [tableView dequeueReusableCellWithIdentifier:ID];
    }

    // 设置模型数据
    cell.status = self.statuses[indexPath.row];

    return cell.height;
}

- (CGFloat)height
{
    // 强制布局cell内部的所有子控件(label根据文字多少计算出自己最真实的尺寸)
    [self layoutIfNeeded];

    // 计算cell的高度
    if (self.status.picture) {
        return CGRectGetMaxY(self.pictureImageView.frame) + 10;
    } else {
        return CGRectGetMaxY(self.text_label.frame) + 10;
    }
}
posted @ 2016-11-24 01:07  azhang_code  阅读(151)  评论(0编辑  收藏  举报