Monday, 1 October 2018

Update UICollectionView header height based on headers UITextview content

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 its hight 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.



from Update UICollectionView header height based on headers UITextview content

No comments:

Post a Comment