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