对于依赖于已解决的内部布局的大小,正确实现intrinsicContentSize

tyl*_*ler 14 layout uiview uilabel ios autolayout

我有一个似乎有效的解决方案,但我想确保它是安全的并按预期使用该工具.我可以将我的问题提炼到这种情况 - 我有一个包含多个垂直堆叠的UILabel的UIView.每个标签都可以填充任意文本,垂直包装和展开标签.在视图中堆叠标签的自动布局约束是微不足道的.我想做的是让UIView通过其所有者传达其首选高度(视图的高度应该适合所有标签)intrinsicContentSize.但是,在我返回适当的高度之前,需要先解决内部布局问题.我的理解是,在返回后[super layoutSubviews],求解器保证完整,这就是我正在做的事情:

- (void)layoutSubviews
{
    [super layoutSubviews];

    // solver's complete, now we can measure?
    [self invalidateIntrinsicContentSize];
}
Run Code Online (Sandbox Code Playgroud)

我的intrinsicContentSize实现是指最后一个标签的框架来计算高度.这一切似乎都适用于我目前的情况,但它让我感到紧张.似乎解算器在布局其内部时要求当前视图的intrinsicContentSize.我不会详细介绍,但我遇到了一个案例,其中这种模式转变为无限循环.通过调整我的一些布局代码,我能够解决这个问题 - 这并没有激发人们的信心.

有一个更好的方法吗?这似乎是一个常见的事情,当我开始研究这个问题时,我认为这就是intrinsicContentSize的用途.我所见过的intrinsicContentSize的实现总是微不足道的 - 维度的硬编码大小,或者测量不依赖于已解决的内部布局的单个视图.

注意,我不能仅通过NSString sizeWith...方法测量标签,因为内部布局太复杂.

注意,我探索了使用systemLayoutSizeFittingSize:,但是从intrinsicContentSize调用它会导致无限循环.

任何回应将不胜感激!提前致谢!

tyl*_*ler 7

我想更新这个线程并关闭这个问题 - 我认为对于其他人来说,这里仍然有价值,因为其他人刚开始使用 AutoLayout 可能会有类似的误解。理解内在内容大小的真正目的很重要 - 这不是典型视图如何将其首选大小传达给其父视图。如果视图使用 AutoLayout 来布局其子视图,那么它将使用定义其内部布局的约束来通知其父级其大小 - 具体而言,它将是将子视图与其父级相关联的约束,这些约束将有助于定义父母的大小。这实际上是 AutoLayout 既神奇又令人沮丧的部分 - 它是导致布局的所有这些约束(视图的内部和外部)的总和。

我认为与多行文本相关的早期 iOS 错误/不一致是导致我走上内部内容大小之路的原因。多行文本仍然不完美,但希望在 iOS10 中更好。