手动计算 tableViewCell 高度与 AutoLayout Cell 高度计算的结合
今天写项目遇到一个特别坑爹的问题, 就是之前的同事是使用纯手码计算 tableViewCell 的高度, 今天有个需求, 在原来的 tableView 上添加5个不同类型的 Cell, 我想这很容易啊, 直接 Xib 计算不就 OK 了,再结合 iOS8 的根据 AutoLayout自动计算Cell高度, 分分钟的时, 没想到坑爹的一幕发生了, 同事是用 frame 排列的之前的 Cell 的内容, 而我是需要 Autolayout 的, 他重写了 -tableView:heightForRowAtIndexPath 方法, 这在 iOS8中与 AutoLayout 结合根本不需要写的, 我一下子无语了, 还好我之前看过在 iOS7 中怎么结合 AutoLayout 计算 Cell 的高度, 于是将它们结合了起来,大致是这样的:
同事之前的代码:
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
PDProduct *product = [self.data objectAtIndex:indexPath.row];
return [PDFinancingProductCell getCellHeightOfProduct:product showLikeView:NO];
}
我使用 Xib 创建出 Cell 设置好约束后, 同样重写了 heightForRowAtIndexPath: 方法
- (void)viewDidLoad {
[super viewDidLoad];
// iOS8 自动 AutoLayoutCell 高度
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 200;
// 注册 Xib Cell
/// 底部3张图片 Cell
[self.tableView registerNib:[UINib nibWithNibName:@"ProThreeImageCell" bundle:nil] forCellReuseIdentifier:@"ProThreeImageCell"];
/// 只有文字描述的 Cell
[self.tableView registerNib:[UINib nibWithNibName:@"ProNoImageCell" bundle:nil] forCellReuseIdentifier:@"ProNoImageCell"];
/// 左边一张图片的 Cell
[self.tableView registerNib:[UINib nibWithNibName:@"ProOneLeftImageCell" bundle:nil] forCellReuseIdentifier:@"ProOneLeftImageCell"];
/// 右边一张图片的 Cell
[self.tableView registerNib:[UINib nibWithNibName:@"ProOneRightImageCell" bundle:nil] forCellReuseIdentifier:@"ProOneRightImageCell"];
/// 底部只有一张图片的 Cell
[self.tableView registerNib:[UINib nibWithNibName:@"ProOneImageCell" bundle:nil] forCellReuseIdentifier:@"ProOneImageCell"];
[self initSubViews];
}
- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
PDProduct *product = [self.data objectAtIndex:indexPath.row];
if (product.show_type == FinacingPro) {
[PDFinancingProductCell getCellHeightOfProduct:product showLikeView:NO];
} else if (product.show_type == ProShowStyleBottomeThreeImage) { // 这种类型的 Cell 底部显示3长图片
// 如果之前计算过高度, 直接从缓冲中取
if (self.cellHeightCaches[indexPath]) {
return self.cellHeightCaches[indexPath] floatValue];
}
ProThreeImageCell *threeImageCell = [tableView dequeueReusableCellWithIdentifier:@"ProThreeImageCell"];
if (!threeImageCell) {
threeImageCell = [ProThreeImageCell proThreeImageCellWithTableView:tableView identifier:@"ProThreeImageCell"];
self.cellCaches[indexPath] = threeImageCell;
}
threeImageCell.product = product;
CGFloat cellHeight = [threeImageCell getCellHeight];
self.cellHeightCaches[indexPath] = @(cellHeight);
return cellHeight;
} else {
.... // 其他几个不同的 XibCell
}
}
在 ProThreeImageCell 中:
+ (instancetype)proThreeImageCellWithTableView:(UITableView *)tableView identifier:(NSString *)identifier {
ProThreeImageCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell) {
NSArray *xibs = [[NSBundle mainBundle] loadNibNamed:@"ProThreeImageCell" owner:nil options:nil];
cell = xibs[0];
}
return cell;
}
// titleLabel 的高度不固定
- (CGFloat)getCellHeight {
self.titleLabel.preferredMaxLayoutWidth = WIDTH_SCREEN - self.bankIconImageView.bounds.size.width - self.toPersonOrPublicImageView.bounds.size.width - 20;
[self.textLabel layoutIfNeeded];
self.titleLabel.text = self.product.title;
[self.contentView layoutIfNeeded];
CGFloat cellHeight = [self.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
return cellHeight + 1.f; // +1.f 注意
}
菜鸟的总结, 愿得到众大神的指点