在 SO 和其他地方有很多关于如何根据子视图的大小计算 UITableView 行的必要高度的好信息。典型的例子,也是我在这里应用的例子,是一个包含可变长度文本标签的单元格。
通常的建议是sizeWithFont:constrainedToSize:lineBreakMode:
在 tableview 的heightForRowAtIndexPath:
. 但是我见过的大多数示例都使用基于标签已知宽度的“魔术”数字。
CGSize constraint = CGSizeMake(224.0, MAXFLOAT); //224 is known to be the width available
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping];
一些更好的示例可能会使用 tableview 的边界,然后为单元格中的其他视图减去幻数或常量,这至少更清晰一些(如果边界在旋转等时发生变化,效果会更好)。
CGSize constraint = CGSizeMake(self.tableview.bounds.size.width - 20 - 10 - 36 - 20, MAXFLOAT); //each non-label width subtracted
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping];
这是常见的方法,但似乎缺乏。谁说其他单元格子视图的宽度,甚至字体,保证不会改变(或者总是在两个地方都努力改变)?
我决定我宁愿让细胞负责提供这个高度。细胞总是知道它的属性。为了做到这一点,我首先让单元格中的所有布局代码都引用了一些局部常量。然后,我向我的自定义单元格类添加了一个类方法,它可以根据自己的字体和大小常量返回任何给定文本段所需的高度。
+ (CGFloat)heightRequiredForText:(NSString *)text usingWidth:(CGFloat)width
{
//a class method that tells the caller how much height is needed for the provided text, based on the cell's size and font constants
CGSize constraintSize = CGSizeMake(width - kMargin - kGap - kMargin - kCheckboxWidth, MAXFLOAT);
CGRect bounds = [text boundingRectWithSize:constraintSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:self.labelFont}
context:nil];
return bounds.size.height;
}
这允许 UITableViewController 简单地提供文本和当前边界的宽度,(即 tableview 的宽度)。可以在单元格子类中更改字体和布局,并且一切都继续“正常工作”。
问题 1
顺便说一句,这合理吗?有没有更好的方法来实现同样的目标?
问题2
这是我在使用这种(以及更标准的)方法时遇到的主要问题。当单元格处于其编辑模式时,标签的宽度会发生变化以适应编辑附件。由于行高是恒定的,并且标签使用自动布局,因此它的高度会增加。
所需的行为是标签的高度保持不变,必要时应使用截断。
我在哪里以及如何实现这一点?我应该在单元格的 setEditing: 中做些什么吗?也许添加另一个约束来限制高度,并打开截断,在编辑时应用相反的 == NO?“滑动删除”模式怎么样 - 我认为这不会触发 setEditing?layoutSubview 怎么样 - 我可以在那里做点什么吗?