为什么 view.frame.width 返回零?

Max*_*axB -1 ios swift

我创建了 stackView 并向其添加了三个标签。我还设置了这些限制

let nameLabel = UILabel()
//set .text, .mode and other for nameLabel
let ellipsisLabel = UILabel()
//set .text, .mode and other for ellipsisLabel
let amountAndMeasureLabel = UILabel()
//set .text, .mode and other for amountAndMeasureLabel

for label in [nameLabel, ellipsisLabel, amountAndMeasureLabel] {
                stackView.addArrangedSubview(label)
            }
NSLayoutConstraint.activate([
                nameLabel.leadingAnchor.constraint(equalTo: stackView.leadingAnchor, constant: 0.0),
                nameLabel.trailingAnchor.constraint(equalTo: ellipsisLabel.leadingAnchor, constant: 0.0),
                nameLabel.widthAnchor.constraint(equalToConstant: nameLabel.intrinsicContentSize.width),
                amountAndMeasureLabel.leadingAnchor.constraint(equalTo: ellipsisLabel.trailingAnchor, constant: 0.0),
                amountAndMeasureLabel.trailingAnchor.constraint(equalTo: stackView.trailingAnchor, constant: 0.0),
                amountAndMeasureLabel.widthAnchor.constraint(equalToConstant: amountAndMeasureLabel.intrinsicContentSize.width)
            ])

nameLabel.frame.width // 0
ellipsisLabel.frame.width // 0
amountAndMeasureLabel.frame.width // 0
Run Code Online (Sandbox Code Playgroud)

我将在 .xib 上演示情况以便更好地理解(我不使用这个 .xib)

在此输入图像描述

但是当我试图获取他们的 .frame.width 时,我得到了零。

Rob*_*ier 6

仅激活约束不会导致视图布局。如果您需要stackView立即布局其子视图,您需要告诉它:

stackView.layoutIfNeeded()
Run Code Online (Sandbox Code Playgroud)

否则,系统将在下次需要时自动收集并应用所有布局更新。由于强制布局可能会导致不必要的计算(如果绘制周期中稍后的某些内容更改了布局),因此通常应该避免调用,.layoutIfNeeded()除非确实需要它。但如果你这样做的话,它是完全支持的。

还有.setNeedsLayout(),它告诉系统视图在下一个绘制周期需要布局。如果某些内容以系统不会注意到的方式更改布局,您应该使用此选项。如果您的更改是通过 UIKit 本身进行的,则通常不需要此操作。UIStackView 在调用后就知道它需要布局.addArrangedSubview。但是如果你改变了布局所依赖的某些数据,你可能需要告诉 UIKit。