在使用autolayout的项目中,单元格的自适应高度,可能有点复杂,特别是对于复杂一点的自定义单元格;那么下面就这个autolayout自适应单元格,通过代码来说明:
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
SGSuggestionRootTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
cell.frame = CGRectMake(0, 0, CGRectGetWidth(tableView.frame), 0);
//标记需要重新布局重新布局
[cell.contentView setNeedsLayout];
//使布局立即生效
[cell.contentView layoutIfNeeded];
// id obj = [[NSArray alloc] objectAtIndex:indexPath.row]
CGRect questionRect = [@"你们网站有人乱发垃圾信息" boundingRectWithSize:CGSizeMake(cell.questionLabel.frame.size.width
, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:14.]} context:nil];
CGRect sugContentRect = [@"你们网站有人乱发垃圾信息,好多广告,希望赶紧清除!" boundingRectWithSize:CGSizeMake(cell.sugContentLabel.frame.size.width
, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:14.]} context:nil];
CGRect fbContentRect = [@"你们网站有人乱发垃圾信息,好多广告,希望赶紧清除!发顺丰撒啊事发地点萨芬撒发顺丰的法师法师嘎斯发噶沙发沙发上防辐射的方式和发上防辐射的方式和发上防辐射的方式和" boundingRectWithSize:CGSizeMake(cell.fbContentLabel.frame.size.width
, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: [UIFont systemFontOfSize:14.]} context:nil];
//15是固定的控件间的间隙
CGFloat sum = questionRect.size.height + sugContentRect.size.height + fbContentRect.size.height + 15;
return sum;
}
以上代码是获取计算单元格的高度,红色字体部分是需要注意的,因为是通过重用机制获取的cell的frame宽度有问题,所以重新设置合适的宽度,然后通过 [cell.contentView setNeedsLayout]; 标记为待重新布局, 通过 [cell.contentView layoutIfNeeded]; 立即调用 layoutsubview方法,从而获取questionLabel、sugContentLabel、fbContentLabel这三个控件根据约束条件生成的width,(为节省资源,可将红色代码放到viewdidload中) 然后通过boundingRectWithSize这个方法和width计算出显示字符串的bound, 得到这些bound后,根据实际情况进行运算获取,将要显示单元格的高度
在 (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 中设置label的高度,在下面的代码中使用的是masonry这个对手写autolayout进行封装的开源类库,代码如:
[label mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.greaterThanOrEqualTo(@(rect.size.height));
}];
需要注意的是,由于使用了autolayout,多行label高度需要设置为大于等于,而不能设置为等于