Search code examples
iosswiftuiviewnslayoutconstraintios-autolayout

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


I am trying to create a ViewBuilder class that sets up views and returns them to the caller. The caller then only has to constraint one view that holds some subviews which are constraint inside the view. That way, I'd like to save some code.

Things will get more clear with the code:

Code inside my 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

Code in the 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
    }

This is the behavior I get: Bricked view constraints

As you can see, the postView, generated from the ViewComponentsBuilder does not enclose its subviews (in this case it's a label containing the post description; the border you see is not from the postView but from the label correctly resizing its height according to the content). This behavior causes the entire view to brick.

I really don't know where the problem is and would be incredibly thankful for some advice. Thanks in advance!


Solution

  • I found the answer: Simply constraint the postView's bottomAnchor to the labels bottomAnchor, like so:

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

    That's all the magic. Everything looks like it should :)