#import <Foundation/Foundation.h> @protocol ZSYAutoLayoutCellProtocol; static CGFloat ZSYDynamicTableViewCellAccessoryWidth = 33; //這個數組用來保存全部類型的自動佈局的Cell類的一個對象,用於後面計算cell高度 static NSMutableArray *cellArray; //先傳出保存的cell對象,而後再用調用者返回設置了全部顯示數據的cell對象,用於計算cell高度須要 typedef id (^setupCellBlock)(id<ZSYAutoLayoutCellProtocol> cellToSetup); @protocol ZSYAutoLayoutCellProtocol <NSObject> //全部cell設置數據 - (void)setupDataItem:(id)data; //計算cell高度 + (CGSize)sizeForCellWithDefaultSize:(CGSize)defaultSize setupCellBlock:(setupCellBlock)block; @end
- (void)setupDataItem:(id)data { //這個方法子類cell重寫,將實體對象設置給cell.contentView.subviews } + (CGSize)sizeForCellWithDefaultSize:(CGSize)defaultSize setupCellBlock:(setupCellBlock)block { __block UITableViewCell *cell = nil; //查看靜態數組內是否已經存在當前Cell類的一個對象 [cellArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { if ([obj isKindOfClass:[[self class] class]]) { cell = obj; *stop = YES; } }]; //若是不存在,建立一個當前Cell類型的對象,並保存到數組。後續計算當前Cell類型對象的高度時,直接使用這個保存的Cell對象 if (!cell) { cell = [[[self class] alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"XZHAutoLayoutCellIdentifier"]; cell.frame = CGRectMake(0, 0, defaultSize.width, defaultSize.height); [cellArray addObject:cell]; } //獲取到設置了屬性值的cell對象[1.先回傳出去 2.再接收Block的一個返回值cell對象] cell = block((id<ZSYAutoLayoutCellProtocol>) cell); //獲取到cell對象的 CGSize // [cell.contentView layoutIfNeeded]; CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; size.width = MAX(defaultSize.width, size.width); size.height = size.height + 1.0f; return size; }
// 實現接口定義的設置實體類對象的方法 - (void)setupDataItem:(id)data { if ([data isKindOfClass:[ZSYEntityModule class]]) { _entity = (ZSYEntityModule *)data; _titleLabel.text = _entity.title; [_contentImageView sd_setImageWithURL:[NSURL URLWithString:_entity.imageURL] placeholderImage:[UIImage imageNamed:@"blankpage_image_Hi"] options:SDWebImageProgressiveDownload]; //UILabel寫上這一句 [_titleLabel layoutIfNeeded]; } }
//給Cell.contentView.subviews分別設置約束,使用VFL - (void)initSubviews { self.backgroundColor = [UIColor whiteColor]; self.accessoryType = UITableViewCellAccessoryNone; self.accessoryView = nil; self.selectionStyle = UITableViewCellSelectionStyleNone; [self.contentView setAutoresizingMask:UIViewAutoresizingFlexibleHeight]; _titleLeftImageView = [[UIImageView alloc] init]; _titleLeftImageView.image = [UIImage imageNamed:@"icon_title"]; _titleLeftImageView.translatesAutoresizingMaskIntoConstraints = NO; _titleLeftImageView.contentMode = UIViewContentModeScaleAspectFill; _titleLabel = [[UILabel alloc] init]; _titleLabel.numberOfLines = 0; _titleLabel.lineBreakMode = NSLineBreakByWordWrapping; _titleLabel.translatesAutoresizingMaskIntoConstraints = NO; _titleLabel.font = [UIFont fontWithName:@"HelveticaNeue-Bold" size:15]; _titleLabel.textColor = [UIColor hex:@"#514647"]; _contentImageView = [[UIImageView alloc] init]; _contentImageView.translatesAutoresizingMaskIntoConstraints = NO; [self.contentView addSubview:_titleLeftImageView]; [self.contentView addSubview:_titleLabel]; [self.contentView addSubview:_contentImageView]; NSDictionary *viewDict = NSDictionaryOfVariableBindings(_titleLeftImageView, _titleLabel, _contentImageView); NSDictionary *metricDict = @{@"sideBuffer1" : @16, @"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}; NSString *vfl = @"H:|-sideBuffer1-[_titleLeftImageView(labelImageSizeWith)]-5-[_titleLabel]-sideBuffer2-|"; [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl options:0 metrics:metricDict views:viewDict]]; vfl = @"H:|-sideBuffer2-[_contentImageView]-sideBuffer2-|"; [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl options:0 metrics:metricDict views:viewDict]]; vfl = @"V:|-vertical_top_Buffer-[_titleLeftImageView]"; [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl options:0 metrics:metricDict views:viewDict]]; vfl = @"V:|-vertical_top_Buffer-[_titleLabel]-vertical_middle_Buffer-[_contentImageView(contentImageSizeHeight)]-vertical_bottom_Buffer-|"; [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl options:0 metrics:metricDict views:viewDict]]; // vfl = @"V:[_contentImageView(contentImageSizeHeight)]-vertical_bottom_Buffer-|"; // [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:vfl options:0 metrics:metricDict views:viewDict]]; // [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.titleLeftImageView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.titleLabel attribute:NSLayoutAttributeTop multiplier:1 constant:0]]; [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.titleLeftImageView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.titleLabel attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]]; // [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:self.titleLeftImageView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.titleLabel attribute:NSLayoutAttributeBottom multiplier:1 constant:0]]; [self.titleLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical]; [self.titleLabel setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal]; //獲取每一個cell重寫後,本身的默認size CGSize defaultSize = [[self class] defaultCellSize]; //注意: 全部UILabel若是須要高度動態改變,必定要設置preferredMaxLayoutWidth最大寬度 self.titleLabel.preferredMaxLayoutWidth = defaultSize.width - [metricDict[@"sideBuffer1"] floatValue] -[metricDict[@"labelImageSizeWith"] integerValue] - 5 - [metricDict[@"sideBuffer2"] integerValue]; }
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { if (![[self cellClass] isDynamic]) { return [self cellDefaultHeight]; } __weak typeof(self) weakSelf = self; //默認 size CGSize defaultSize = [[self cellClass] defaultCellSize]; //計算後自適應的 size CGSize cellSize = [[self cellClass] sizeForCellWithDefaultSize:defaultSize setupCellBlock:^id(id<ZSYAutoLayoutCellProtocol> cellToSetup) { NSArray *dataList = [weakSelf dataSource]; if ([self sectionCount] == 1) {//一維數組 [cellToSetup setupDataItem:dataList[[indexPath row]]]; } else {//二惟數組 NSArray *sectionArray = dataList[indexPath.section]; id obj = sectionArray[indexPath.row]; [cellToSetup setupDataItem:obj]; } return cellToSetup; }]; return cellSize.height; }