来源:http ://www.objc.io/issue-3/advanced-auto-layout-toolbox.html
多行文本的内在内容大小
UILabel 和 NSTextField 的内在内容大小对于多行文本是不明确的。文本的高度取决于行的宽度,这在解决约束时尚未确定。为了解决这个问题,这两个类都有一个名为 preferredMaxLayoutWidth 的新属性,它指定了用于计算内在内容大小的最大线宽。
由于我们通常事先不知道这个值,因此我们需要采取两步的方法来解决这个问题。首先我们让 Auto Layout 完成它的工作,然后我们在布局过程中使用生成的框架来更新首选的最大宽度并再次触发布局。
- (void)layoutSubviews
{
[super layoutSubviews];
myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
[super layoutSubviews];
}
第一次调用 [super layoutSubviews] 是标签获取其框架集所必需的,而第二次调用是在更改后更新布局所必需的。如果我们省略第二次调用,我们会得到一个 NSInternalInconsistencyException 错误,因为我们在布局过程中进行了更改,需要更新约束,但我们没有再次触发布局。
我们也可以在标签子类本身中执行此操作:
@implementation MyLabel
- (void)layoutSubviews
{
self.preferredMaxLayoutWidth = self.frame.size.width;
[super layoutSubviews];
}
@end
在这种情况下,我们不需要先调用 [super layoutSubviews],因为当 layoutSubviews 被调用时,我们已经在标签本身上有了一个框架。
为了从视图控制器级别进行此调整,我们挂钩到 viewDidLayoutSubviews。此时,第一个 Auto Layout pass 的框架已经设置好了,我们可以使用它们来设置首选的最大宽度。
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
[self.view layoutIfNeeded];
}
最后,确保标签上没有明确的高度约束,其优先级高于标签的内容压缩阻力优先级。否则它将胜过计算的内容高度。确保检查所有可能影响标签高度的约束。