iOS6~10 UITableViewCell 之行高算式精要
太阳火神的美丽人生 (http://blog.csdn.net/opengl_es)
本文遵循“署名-非商业用途-保持一致”创作公用协议
转载请保留此句:太阳火神的美丽人生 - 本博客专注于 敏捷开发及移动和物联设备研究:iOS、Android、HTML5、Arduino、pcDuino,否则,出自本博客的文章拒绝转载或再转载,谢谢合作。
简言之,自动布局耳。
@property(nonatomic) CGFloat rowHeight;
iOS 7.0 引入
@property(nonatomic) CGFloat estimatedRowHeight;
const CGFloat UITableViewAutomaticDimension;
Requests that UITableView use the default value for a given dimension.
初始设置
- (void)viewDidLoad { [super viewDidLoad]; self.tableView.estimatedRowHeight = 100; self.tableView.rowHeight = UITableViewAutomaticDimension;
行高代理方法实现
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { // 用 cell 标识从缓存中提取 cell 实例,如果没有,系统自动按 storyboard 中 cell 原型或自注山的 cell 创建 NSString *identifier = @"main_cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; // 在自动计算高度前,先填充 cell 的内容 // 禁止将 AutoresizingMask 转换成约束 cell.contentView.translatesAutoresizingMaskIntoConstraints = NO; // 表视图的外框宽度 CGFloat contentViewWidth = CGRectGetWidth(self.tableView.bounds); // 使用该宽度构建表视图单元的内容视图的宽度约束 NSLayoutConstraint *widthFenceConstraint = [NSLayoutConstraint constraintWithItem:cell.contentView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:contentViewWidth]; // 约束表单元内容视图的宽度 [cell.contentView addConstraint:widthFenceConstraint]; // 确保表单元内容视图中元素布局自顶向下连贯,内容视图的顶边和底边有约束,左右一样要连贯,才能计算出正确的值,否则为 0 或 10001,也许还有别的 CGFloat fittingHeight = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingExpandedSize].height; // 高度由自动布局用 systemLayoutSizeFittingSize 算完了,约束可以拿下去了 [cell.contentView removeConstraint:widthFenceConstraint]; // 需要分隔线并打开时,按屏幕映射系数把这一个单位的实际像素加上去。 //return fittingHeight+2*1/[UIScreen mainScreen].scale; return fittingHeight; }
总结:
其中注释已详述,关键两点,
一是表单元的内容视图没有四边固定约束,所以会缺少约束,而其宽度一般为表宽,故加此约束,
二是高度由内容撑起,其包裹内容,以确定上下边的约束,故内容视图上下边也一定要有约束。(补充:一定要让内容视图的顶、底直接或间接相连以约束)
原考虑直接 controll-drag 建立表单元内容视图与外部各层容器的约束,以确保其宽度为明确的,但实际是不允许这样做的,所以得从代码中加入,否则 systemLayoutSizeFittingSize 计算得到的值为10001 或 0(网友结果,本人未遇)。
另外,
可以使用网上流行的 FDTemplateLayoutCell
再有约束封装开源库 Masonry
近期翻译了官方有关自动布局多篇文档,官方建议的 Stack View,也许作为如 Android 线性布局类似的工具,也许会有更多版本提供吧,不如干脆采用 Android 同样的布局算了,可是面子又过意不去,何如?