iOS AutoLayout多
下面的问题是这一类的延续:
iOS:自动布局中的多行UILabel
主要思想是每个视图都应该声明它是“首选”(内在)大小,以便AutoLayout可以知道如何正确显示它。 UILabel仅仅是一种情况的例子,在这种情况下,视图本身并不知道它需要显示的尺寸。 这取决于提供的宽度。
正如mwhuss指出的那样,setPreferredMaxLayoutWidth完成了将标签跨越多行的技巧。 但这不是这里的主要问题。 问题是我何时以及何时将这个宽度值作为setPreferredMaxLayoutWidth的参数发送。
我设法做出一些看起来合法的东西,所以如果我有任何问题,请纠正我,如果你知道更好的方法,请告诉我。
在UIView的
-(CGSize) intrinsicContentSize
根据self.frame.width为我的UILabels设置了PreferredMaxLayoutWidth。
UIViewController的
-(void) viewDidLayoutSubviews
是我知道的第一个回调方法,其中主视图的子视图是用屏幕上居住的确切帧指定的。 然后,从那个方法中,我对我的子视图进行操作,使它们的内在大小无效,以便UILabel根据指定给它们的宽度分成多行。
看起来令人讨厌的是,如果你有一些约束条件明确地为你定义了这个宽度,那么UILabel不会默认它的宽度作为首选的最大布局宽度。
几乎在每种情况下,我都使用Autolayout下的标签,一旦我的布局的其余部分执行完毕,首选的最大布局宽度就是标签的实际宽度。
所以,为了自动发生这种情况,我使用了一个UILabel子类,它覆盖了setBounds:
在这里,调用超级实现,然后, 如果不是这种情况 ,请将首选最大布局宽度设置为边界大小宽度。
重点非常重要 - 设置首选最大布局会导致执行另一个布局传递,因此最终可能会出现无限循环。
在高级自动布局工具箱的“多行文本的内部内容大小”部分中,有关objc.io的这个问题的答案。 以下是相关信息:
对于多行文本,UILabel和NSTextField的内在内容大小不明确。 文本的高度取决于线条的宽度,这在解决约束时尚未确定。 为了解决这个问题,两个类都有一个名为preferredMaxLayoutWidth的新属性,它指定了用于计算内在内容大小的最大行宽。
由于我们通常不会提前知道这个值,所以我们需要采取两步走的方法才能做到这一点。 首先,我们让自动布局执行其工作,然后使用布局过程中的结果帧再次更新首选最大宽度和触发布局。
他们在视图控制器中使用的代码:
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
myLabel.preferredMaxLayoutWidth = myLabel.frame.size.width;
[self.view layoutIfNeeded];
}
看看他们的帖子,还有更多关于为什么需要两次布局的信息。
更新
我的原始答案似乎很有帮助,所以我没有在下面留下它,但是,在我自己的项目中,我发现了一个更可靠的解决方案,可以解决iOS 7和iOS 8中的错误。https://github.com/nicksnyder/ios胰岛β细胞布局
原始答案
这是一个适用于iOS 7和iOS 8的完整解决方案
目标C
@implementation AutoLabel
- (void)setBounds:(CGRect)bounds {
if (bounds.size.width != self.bounds.size.width) {
[self setNeedsUpdateConstraints];
}
[super setBounds:bounds];
}
- (void)updateConstraints {
if (self.preferredMaxLayoutWidth != self.bounds.size.width) {
self.preferredMaxLayoutWidth = self.bounds.size.width;
}
[super updateConstraints];
}
@end
迅速
import Foundation
class EPKAutoLabel: UILabel {
override var bounds: CGRect {
didSet {
if (bounds.size.width != oldValue.size.width) {
self.setNeedsUpdateConstraints();
}
}
}
override func updateConstraints() {
if(self.preferredMaxLayoutWidth != self.bounds.size.width) {
self.preferredMaxLayoutWidth = self.bounds.size.width
}
super.updateConstraints()
}
}
链接地址: http://www.djcxy.com/p/28219.html
上一篇: iOS AutoLayout multi
下一篇: UIButton with background image: title text randomly does not appear