我正在尝试创建一个ViewBuilder类来设置视图并将其返回给调用者。然后,调用者只需约束一个包含一些子视图的视图,这些子视图在该视图内是受约束的。这样,我想保存一些代码。
使用代码,事情会变得更清楚:
我的“收藏夹视图单元”中的代码:
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类中的代码:
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不会包含其子视图(在这种情况下,它是包含帖子说明的标签; 您看到的边框不是来自postView而是正确调整了标签的大小)其高度取决于内容)。此行为导致整个视图变砖。
我真的不知道问题出在哪里,并且非常感谢您提供一些建议。预先感谢!
答案 0 :(得分:2)
您的视图尺寸不正确,因为您返回的视图只是其中包含子视图的普通UIView
实例。 sizeThatFits(_:)
的默认UIView
实现只是返回CGSize.zero
。
您在这里有几个选择:
PostView
子类的UIView
类。您应该将DefaultLabel
实例添加为该视图的子视图,类似于在generatePostView(postItem:) -> UIView
中的操作。然后,您应该在sizeThatFits(_:)
中实现PostView
,在其中它使用DefaultLabel
的{{1}}值来计算要返回的正确大小。sizeThatFits(_:)
方法中,仅返回generatePostView(postItem:) -> UIView
实例,而不是将其添加到另一个postDescription
实例中。我将其列为您的第二个选项,因为我猜想您打算向容器视图中添加不仅仅是UIView
的更多子视图,因此选项1将来更容易添加更多子视图。答案 1 :(得分:0)
如layoutSubviews
文档中所述,切勿直接调用它。将其修改为正确的
/* postView.layoutSubviews() */
postView.setNeedsLayout()
postView.layoutIfNeeded()
答案 2 :(得分:0)
我找到了答案:只需将postView
的bottomAnchor约束为标签bottomAnchor,就像这样:
postView.bottomAnchor.constraint(equalTo: postDescription.bottomAnchor).isActive = true
这就是魔术。一切看起来都应该:)