强制高度为零的 UIView 布局其子视图

Force UIView with zero height to lay out its subviews

我有一个 UIView,里面有一些标签。标签具有取决于文本的动态高度,并且它们对父视图和彼此具有垂直间距约束,从而为父视图提供其高度。最后一个标签的底部和父视图底部之间的约束设置为具有较低的优先级。

此外,父视图有一个高度限制,我在 viewDidLoad 中将其设置为 0。这会折叠视图并将所有标签向下推,因为最后一个底部约束具有较低的优先级。然后我有一个按钮,我可以在其中切换父视图的高度约束,opens/closes 它:

@IBAction func viewInfoButtonTapped(_ sender: Any) {
    viewInfoButton.isSelected = !viewInfoButton.isSelected
    
    self.infoHeightConstraint.isActive = !self.viewInfoButton.isSelected
    UIView.animate(withDuration: 0.25) {
        self.view.layoutIfNeeded()
    }
}

我的问题是在我第一次展开父视图之前不会设置标签的动态高度,所以我得到的不是简单显示标签的动画,而是显示标签并增长的效果同时在高度上。第一次展开后,高度已经设置好,后续展开正确效果。

如何强制视图在第一次展开之前正确布置约束? 我试过调用setNeedsLayout()layoutIfNeeded(),但似乎没有效果。

在每个标签上将 垂直 Content Compression Resistance 优先级设置为 Required (1000)

或者,由于您可能会在 运行 时循环遍历它们以设置每个中的文本,您可以通过代码完成:

label.text = someString
label.setContentCompressionResistancePriority(.required, for: .vertical)

这应该可以修复您不想要的初始“拉伸”。

如果您仍然看到拉伸(不应该,但以防万一),您也可以致电 sizeToFit():

label.text = someString
label.setContentCompressionResistancePriority(.required, for: .vertical)
label.sizeToFit()