iOS 自定义不等高的cell

来源:互联网 发布:java汉化版 编辑:程序博客网 时间:2024/05/01 07:11

自定义不等高的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;    }}
1 0
原创粉丝点击