UICollectionView header dynamic height using Auto Layout

后端 未结 5 1082
臣服心动
臣服心动 2020-11-30 02:45

I have a UICollectionView with a header of type UICollectionReusableView.

In it, I have a label whose length varies by user input.

5条回答
  •  长情又很酷
    2020-11-30 03:03

    You could achieve it by implementing the following:

    The ViewController:

    class ViewController: UIViewController {
        @IBOutlet weak var collectionView: UICollectionView!
    
        // the text that you want to add it to the headerView's label:
        fileprivate let myText = "Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Nam liber te conscient to factor tum poen legum odioque civiuda."
    }
    
    extension ViewController: UICollectionViewDataSource {
        func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
            switch kind {
            case UICollectionElementKindSectionHeader:
                let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind,
                                                                                 withReuseIdentifier: "customHeader",
                                                                                 for: indexPath) as! CustomCollectionReusableView
    
                headerView.lblTitle.text = myText
                headerView.backgroundColor = UIColor.lightGray
    
                return headerView
            default:
                fatalError("This should never happen!!")
            }
        }
    
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return 100
        }
    
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "customCell", for: indexPath)
    
            cell.backgroundColor = UIColor.brown
            // ...
    
            return cell
        }
    }
    
    extension ViewController: UICollectionViewDelegateFlowLayout {
        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
            // ofSize should be the same size of the headerView's label size:
            return CGSize(width: collectionView.frame.size.width, height: myText.heightWithConstrainedWidth(font: UIFont.systemFont(ofSize: 17)))
        }
    }
    
    
    extension String {
        func heightWithConstrainedWidth(font: UIFont) -> CGFloat {
            let constraintRect = CGSize(width: UIScreen.main.bounds.width, height: CGFloat.greatestFiniteMagnitude)
            let boundingBox = self.boundingRect(with: constraintRect, options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSFontAttributeName: font], context: nil)
    
            return boundingBox.height
        }
    }
    

    The custom UICollectionReusableView:

    class CustomCollectionReusableView: UICollectionReusableView {
        @IBOutlet weak var lblTitle: UILabel!
    
        override func awakeFromNib() {
            super.awakeFromNib()
    
            // setup "lblTitle":
            lblTitle.numberOfLines = 0
            lblTitle.lineBreakMode = .byWordWrapping
            lblTitle.sizeToFit() 
        }
    }
    

提交回复
热议问题