6

I have a UICollectionViewController header cell that displays information for a business.

A business may or may not have a description.

In my header cell I set a business object, and then set all the text for the labels etc. In here I also try calculating the required text field height based off of this post

What I need is to actually set my header cells height dynamically in the UICollectionViewController where it is used.

BusinessDetailHeader class:

    var maxTextViewHeight: CGFloat = 0

    var business: Business? {
        didSet {
            guard let imageUrl = business?.logoUrl else {return}

            let url = URL(string: imageUrl)
            logoView.kf.setImage(with: url)
            headerImageView.kf.setImage(with: url)

            guard let businessName = business?.name else {return}
            guard let address = business?.address else {return}
            guard let hoursOfOperation = business?.hoursOfOperation else {return}
            guard let phoneNumber = business?.phoneNumber else {return}

            businessNameLabel.text = businessName
            addressLabel.text = address
            hoursofOperationLabel.text = hoursOfOperation
            phoneNumberLabel.text = phoneNumber

            if let description = business?.description {
                detailsTextField.text = description
                let amountOfLinesToBeShown:CGFloat = 6
                if let height = detailsTextField.font?.lineHeight {
                    maxTextViewHeight = height * amountOfLinesToBeShown
                }
            }
        }
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
        layoutViews()
    }

    fileprivate func layoutViews() {
        addSubview(headerImageView)
        headerImageView.anchor(top: topAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 130)

        //ADJUST DETAIL HEIGHT HERE BASED ON CALCULATED HEIGHT FOR TEXTVIEW
        addSubview(detailView)
        detailView.anchor(top: headerImageView.bottomAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 200+maxTextViewHeight)

        detailView.addSubview(businessNameLabel)
        businessNameLabel.anchor(top: logoView.bottomAnchor, left: nil, bottom: nil, right: nil, paddingTop: 4, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
        businessNameLabel.centerXAnchor.constraint(equalTo: detailView.centerXAnchor).isActive = true

        detailView.addSubview(detailsTextField)
        detailsTextField.anchor(top: businessNameLabel.bottomAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: maxTextViewHeight)


        detailView.addSubview(addressLabel)
        addressLabel.anchor(top: detailsTextField.bottomAnchor, left: nil, bottom: nil, right: nil, paddingTop: 4, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
        addressLabel.centerXAnchor.constraint(equalTo: detailView.centerXAnchor).isActive = true

        detailView.addSubview(hoursofOperationLabel)
        hoursofOperationLabel.anchor(top: addressLabel.bottomAnchor, left: nil, bottom: nil, right: nil, paddingTop: 4, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
        hoursofOperationLabel.centerXAnchor.constraint(equalTo: detailView.centerXAnchor).isActive = true

        detailView.addSubview(phoneNumberLabel)
        phoneNumberLabel.anchor(top: hoursofOperationLabel.bottomAnchor, left: nil, bottom: nil, right: nil, paddingTop: 4, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
        phoneNumberLabel.centerXAnchor.constraint(equalTo: detailView.centerXAnchor).isActive = true

    }

The height is updated properly with no issues but sometimes when the height is too big, the text and all the following elements overflow out of the header cell. I think this has to do with how I address the height of the cell in my UICollecitonViewController.
I set it's height like this:

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {

    return CGSize(width: view.frame.width, height: 330)
}

The height of 330 here needs to be dynamic. Is this possible? Should I be setting the height property like this? I've seen posts like this one that try addressing this, but the solutions don't seem like they are the best.

Hemant Singh Rathore
  • 2,153
  • 1
  • 24
  • 38
mufc
  • 695
  • 3
  • 16
  • 31
  • Did you tried the solution mentioned in this post? https://stackoverflow.com/questions/25642493/dynamic-uicollectionview-header-size-based-on-uilabel?noredirect=1&lq=1 – Hemant Singh Rathore Oct 01 '18 at 11:33
  • Have you seen this https://stackoverflow.com/questions/39825290/make-uicollectionview-header-dynamic-height – DionizB Oct 01 '18 at 13:02

1 Answers1

0

Please check this link, it will be really helpful in how to make UIcollectionView header dynamic height?. Basically you need to set autolayout constraint according to your requirement; Need to call setNeedlayout() in referenceSizeForHeaderInSection (collectionViewFlowLayout delegate) method.