标签:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { //不使用高度自适应的cell,返回其设置的默认高度 if (![[self cellClass] isDynamic]) { return [self cellDefaultHeight]; } __weak typeof(self) weakSelf = self; //每个Cell类设置的,默认Size CGSize defaultSize = [[self cellClass] defaultCellSize]; //计算后自适应的 size CGSize cellSize = [[self cellClass] sizeForCellWithDefaultSize:defaultSize setupCellBlock:^id(id<ZSYAutoLayoutCellProtocol> cellToSetup) { NSArray *dataList = [weakSelf dataSource]; id obj = nil; //取出当前cell,要显示的实体对象 if ([self sectionCount] == 1) { //dataSource是一维数组 obj = dataList[[indexPath row]]; } else { //dataSource是一维数组 NSArray *sectionArray = dataList[indexPath.section]; obj = sectionArray[indexPath.row]; } //让cell根据实体对象【决定哪些view显示数据,显示什么数据,让cell针对当前实体对象的属性,初始化cell.contentView.subViews 】 [cellToSetup setupDataItem:obj]; //返回一个设置完了显示数据、设置好内部subViews约束的cell对象 return cellToSetup; }]; return cellSize.height; }
+ (CGSize)sizeForCellWithDefaultSize:(CGSize)defaultSize setupCellBlock:(setupCellBlock)block { __block ZSYBaseCell *cell = nil; //使用一个静态变量数组cellArray保存所有需要适配高度的Cell类的一个唯一的对象,方便后续计算cell设置好数据后的高度 //先从静态数组查找,是否存在当前需要适配高度的cell类型的一个对象 [cellArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { if ([obj isKindOfClass:[[self class] class]]) { cell = obj; *stop = YES; } }]; //如果没找到,就创建一个新的cell对象,并保存到静态数组,方便后续使用 if (!cell) { cell = [[[self class] alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"XZHAutoLayoutCellIdentifier"]; cell.frame = CGRectMake(0, 0, defaultSize.width, defaultSize.height); [cellArray addObject:cell]; } //针对一些cell不同数据,cell内部的subViews发生增加、减少类似的情况。通过子类cell重写这个方法,完成在不同的实体数据时,增加删除subviews [cell resetSubviews]; //获取到设置了属性值的cell对象【会执行一次cell的setupData方法】 cell = block((id<ZSYAutoLayoutCellProtocol>) cell); //最好写上 [cell setNeedsLayout]; [cell layoutIfNeeded]; //使用系统函数,计算得到cell的高度 //注意: 【必须在cell对象调用setupData: 时,对内部subviews正确设置约束,此时才能正确计算出高度】 CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; //加上一个1.0f,cell底部的分割线 size.height += 1.0f; //返回高度 return size; }
效果图:
cell结构:
一个imageview,一个label, 多张不固定的图片、每个图片可以有一个优惠的圆形label
// 第一步、cell在init初始化时,创建公共的subviews添加到contentView,并设置约束 - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { [self initSubviews]; } return self; } - (void)initSubviews { _subViews = [NSMutableArray array]; self.backgroundColor = [UIColor whiteColor]; self.accessoryType = UITableViewCellAccessoryNone; self.accessoryView = nil; self.selectionStyle = UITableViewCellSelectionStyleNone; _titleLeftImageView = [[UIImageView alloc] init]; _titleLeftImageView.image = [UIImage imageNamed:@"icon_title"]; _titleLeftImageView.translatesAutoresizingMaskIntoConstraints = NO; _titleLeftImageView.contentMode = UIViewContentModeScaleAspectFill; _titleLabel = [[UILabel alloc] init]; _titleLabel.textAlignment = NSTextAlignmentLeft; _titleLabel.numberOfLines = 0; _titleLabel.lineBreakMode = NSLineBreakByWordWrapping; _titleLabel.translatesAutoresizingMaskIntoConstraints = NO; _titleLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:15]; _titleLabel.textColor = [UIColor hex:@"#514647"]; [self.contentView addSubview:_titleLeftImageView]; [self.contentView addSubview:_titleLabel]; @weakify(self); [self.contentView mas_makeConstraints:^(MASConstraintMaker *make) { @strongify(self); make.edges.equalTo(self); make.width.equalTo(self); }]; //一定要给自动换行计算高度的label,设置最大宽度 [self preferMaxWidthLabels]; // [self setNeedsUpdateConstraints]; // [self updateConstraintsIfNeeded]; }
// 第二步、 给Label设置最大宽度 - (void)preferMaxWidthLabels { _metricDict = @{ @"sideBuffer1" : @12, @"sideBuffer2" : @10, @"vertical_top_Buffer" : @12, @"vertical_middle_Buffer" : @16, @"vertical_bottom_Buffer" : @12.5, @"labelImageSizeWith" : @(_titleLeftImageView.image.size.width), @"labelImageSizeHeight" : @(_titleLeftImageView.image.size.height), @"contentImageSizeHeight" : @181 }; // [self.titleLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical]; // [self.titleLabel setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal]; CGSize defaultSize = [[self class] defaultCellSize]; _titleLabel.preferredMaxLayoutWidth = defaultSize.width - [_metricDict[@"sideBuffer1"] floatValue] -[_metricDict[@"labelImageSizeWith"] integerValue] - 5 - [_metricDict[@"sideBuffer2"] integerValue]; }
// 第三步、tableview代理函数,返回当前显示cell的方法,取出当前cell即将显示的实体对象,然后调用cell对象的 设置数据方法 - (void)setupDataItem:(id)data { if ([data isKindOfClass:[ZSYEntityModule class]]) { _entity = (ZSYEntityModule *)data; _titleLabel.text = _entity.title; //对当前传入实体对象,增加或修改,cell.contentView.subviews [self customLayoutSubviews]; //马上执行系统的 updateConstraints方法 [self setNeedsUpdateConstraints]; [self updateConstraintsIfNeeded]; } }
- (void)customLayoutSubviews { //取出当前要显示的图片张数,依次创建subview,并添加到cell.contentView for (NSString *url in _entity.hots) { __block UIImageView *subView = [[UIImageView alloc] init]; [self.contentView addSubview:subView]; UILabel *icon = [self newIcon]; [subView addSubview:icon]; [icon mas_makeConstraints:^(MASConstraintMaker *make) { make.centerY.mas_equalTo(subView.mas_top); make.right.mas_equalTo(subView.mas_right).offset(-5); make.size.mas_equalTo(CGSizeMake(Cordius*2 , Cordius*2)); }]; //测试设置图片 // if ([url containsString:@"http"]) { // [subView sd_setImageWithURL:[NSURL URLWithString:url] // placeholderImage:[UIImage imageNamed:@"blankpage_image_Hi"] // options:SDWebImageProgressiveDownload]; // } else { [subView setImage:[UIImage imageNamed:url]]; // } _lastView = subView; [_subViews addObject:subView]; } }
// 最后就是重写系统方法,更新约束 - (void)updateConstraints { @weakify(self); CGFloat width = [_metricDict[@"labelImageSizeWith"] integerValue]; CGFloat height= [_metricDict[@"labelImageSizeHeight"] integerValue]; [_titleLeftImageView mas_makeConstraints:^(MASConstraintMaker *make) { @strongify(self); make.top.mas_equalTo(self.contentView.mas_top).offset(14); make.left.mas_equalTo(self.contentView.mas_left).offset(12); make.size.mas_equalTo(CGSizeMake(width, height)); }]; [_titleLabel mas_makeConstraints:^(MASConstraintMaker *make) { @strongify(self); make.top.mas_equalTo(self.contentView.mas_top).offset(12).priority(751); make.left.mas_equalTo(self.titleLeftImageView.mas_right).offset(5); }]; __block UIImageView *last = nil; for (int i = 0; i < _subViews.count; i++) { UIImageView *subView = _subViews[i]; [subView mas_makeConstraints:^(MASConstraintMaker *make) { @strongify(self); make.left.mas_equalTo(self.contentView.mas_left).offset(10); make.right.mas_equalTo(self.contentView.mas_right).offset(-10); if (last) { make.top.mas_equalTo(last.mas_bottom).offset(Cordius+2).priority(749); } else { make.top.mas_equalTo(self.titleLabel.mas_bottom).offset(15).priority(749); } make.height.mas_equalTo(@180); }]; last = subView; } [self.contentView mas_makeConstraints:^(MASConstraintMaker *make) { make.bottom.mas_equalTo(last.mas_bottom).offset(10); }]; //一定要写 [super updateConstraints]; }
AutoLayout五、使用Masonry完成UITableViewCell的自适应高度
标签:
原文地址:http://www.cnblogs.com/xiongzenghui/p/4684763.html