Swift UIView 的 sizeToFit() 总是返回 0 的高度

Swift UIView's sizeToFit() always returning 0 in height

我正在尝试创建一个 ViewBuilder class 来设置视图并将它们 returns 给调用者。然后调用者只需要约束一个视图,该视图包含一些在视图内受约束的子视图。这样,我想节省一些代码。

代码会让事情变得更清楚:

我的 Collection-View-Cell 中的代码:

let postView = ViewComponentsBuilder.generatePostView(postItem: contentInteraction!.nativeContent as! Post)
postView.layer.borderWidth = 1
self.contentView.addSubview(postView)
postView.anchor(top: profileImageView.bottomAnchor, left: self.contentView.leftAnchor, bottom: nil, right: self.contentView.rightAnchor, paddingTop: 0, paddingLeft: 16, paddingBottom: 0, paddingRight: 16, width: 0, height: 0)
postView.layoutSubviews()

postView.sizeToFit()
print(postView.frame.height) // always prints 0

ViewBuilder 中的代码Class:

static func generatePostView(postItem: Post) -> UIView {

        let postDescription: DefaultLabel = {
            let lbl = DefaultLabel(labelFont: UIFont(name: "Montserrat-Medium", size: 16)!, labelTextColor: .black, labelText: "")
            lbl.numberOfLines = 0
            lbl.text = postItem.content.message
            lbl.layer.borderWidth = 1
            return lbl
        }()

        let postView = UIView()

        postView.addSubview(postDescription)
        postDescription.anchor(top: postView.topAnchor, left: postView.leftAnchor, bottom: nil, right: postView.rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
        postDescription.sizeToFit()

        postView.layoutSubviews()

        return postView
    }

这是我得到的行为:

如您所见,从 ViewComponentsBuilder 生成的 postView 没有包含其子视图(在本例中它是一个包含 post 描述的标签;边框您看到的不是来自 post 视图,而是来自根据内容 正确调整高度的标签。此行为导致整个视图变砖。

我真的不知道问题出在哪里,非常感谢您提供一些建议。提前致谢!

layoutSubviews 的文档中所述,永远不应直接调用它。修改为正确的

/* postView.layoutSubviews() */

  postView.setNeedsLayout()
  postView.layoutIfNeeded()

您的视图未正确调整大小,因为您 return 的视图只是一个普通的 UIView 实例,其中有一个子视图。 UIView 的默认 sizeThatFits(_:) 实现只是 return CGSize.zero.

这里有几个选项:

  1. 创建一个 PostView class 子 class 是 UIView。您应该添加一个 DefaultLabel 实例作为该视图的子视图,类似于您在 generatePostView(postItem:) -> UIView 中的做法。然后,您应该在 PostView 中实现 sizeThatFits(_:),它使用 DefaultLabelsizeThatFits(_:) 值来计算 return.
  2. 的正确大小
  3. 在您的 generatePostView(postItem:) -> UIView 方法中,只需 return postDescription 实例,而不是将其添加到另一个 UIView 实例。我将此列为您的第二个选项,因为我猜您计划向容器视图添加更多子视图,而不仅仅是 postDescription,因此选项 1 将来更容易添加更多子视图。

我找到了答案:只需将 postView 的 bottomAnchor 约束到标签 bottomAnchor,如下所示:

postView.bottomAnchor.constraint(equalTo: postDescription.bottomAnchor).isActive = true

这就是所有的魔法。一切看起来都应该如此:)