我有一个只包含 UILabel 的视图.此标签包含多行文本.父级具有可变宽度,可以使用平移手势调整大小.我的问题是,当我调整 UILabel 的大小时,它不会重新计算其高度以使所有内容仍然可见,它只是将其切断.
I've got a view that contains only a UILabel. This label contains multiline text. The parent has a variable width that can be resized with a pan gesture. My problem is that when I do this resizing the UILabel does not recalculate its height such that all of the content is still visible, it simply cuts it off.
我已经设法通过一些 hack 来修复它,但运行起来非常慢:
I've managed to fix it with a bit of a hack but it is horribly slow to run:
- (void)layoutSubviews {
CGSize labelSize = [self.labelDescription sizeThatFits:CGSizeMake(self.frame.size.width, FLT_MAX)];
if (self.constraintHeight) {
[self removeConstraint:self.constraintHeight];
}
self.constraintHeight = [NSLayoutConstraint constraintWithItem:self.labelDescription attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:labelSize.height];
[self addConstraint:self.constraintHeight];
[super layoutSubviews];
}
这不应该通过自动布局自动发生吗?
Shouldn't this happen automatically with autolayout?
编辑
我的视图结构是:
UIScrollView
---> UIView
---> UILabel
以下是 UIScrollView 的约束:
Here are the constraints on the UIScrollView:
<NSLayoutConstraint:0x120c4860 H:|-(>=32)-[DescriptionView:0x85c81c0] (Names: '|':UIScrollView:0x85db650 )>,
<NSLayoutConstraint:0x120c48a0 H:|-(32@900)-[DescriptionView:0x85c81c0] priority:900 (Names: '|':UIScrollView:0x85db650 )>,
<NSLayoutConstraint:0x120c48e0 H:[DescriptionView:0x85c81c0(<=576)]>,
<NSLayoutConstraint:0x120c4920 H:[DescriptionView:0x85c81c0]-(>=32)-| (Names: '|':UIScrollView:0x85db650 )>,
<NSLayoutConstraint:0x120c4960 H:[DescriptionView:0x85c81c0]-(32@900)-| priority:900 (Names: '|':UIScrollView:0x85db650 )>,
<NSLayoutConstraint:0x8301450 DescriptionView:0x85c81c0.centerX == UIScrollView:0x85db650.centerX>,
以下是对 UIView 的约束:
Here are the constraints on the UIView:
<NSLayoutConstraint:0x85c4580 V:|-(0)-[UILabel:0x85bc7b0] (Names: '|':DescriptionView:0x85c81c0 )>,
<NSLayoutConstraint:0x85c45c0 H:|-(0)-[UILabel:0x85bc7b0] (Names: '|':DescriptionView:0x85c81c0 )>,
<NSLayoutConstraint:0x85c9f80 UILabel:0x85bc7b0.trailing == DescriptionView:0x85c81c0.trailing>,
<NSLayoutConstraint:0x85c9fc0 UILabel:0x85bc7b0.centerY == DescriptionView:0x85c81c0.centerY>
UILabel 本身对它没有任何限制,除了将其固定到其父对象的边缘
The UILabel itself has no constraints on it, aside from pinning it to the edges of its parent
在向 Apple 提出错误后,我已修复此问题.多行文本需要两次布局的问题,这一切都依赖于属性 preferredMaxLayoutWidth
I've fixed this issue after raising a bug with Apple. The issue that multiline text requires a two-pass approach to layout and it all relies on the property preferredMaxLayoutWidth
以下是需要添加到包含多行标签的视图控制器的相关代码:
Here is the relevant code that needs to be added to a view controller that contains a multiline label:
- (void)viewWillLayoutSubviews
{
// Clear the preferred max layout width in case the text of the label is a single line taking less width than what would be taken from the constraints of the left and right edges to the label's superview
[self.label setPreferredMaxLayoutWidth:0.];
}
- (void)viewDidLayoutSubviews
{
// Now that you know what the constraints gave you for the label's width, use that for the preferredMaxLayoutWidth—so you get the correct height for the layout
[self.label setPreferredMaxLayoutWidth:[self.label bounds].size.width];
// And then layout again with the label's correct height.
[self.view layoutSubviews];
}
这篇关于iOS Autolayout:调整大小父视图中的 UILabels 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!