Dynamic UICollectionView header size based on UILabel

前端 未结 8 1928
梦谈多话
梦谈多话 2020-12-08 04:51

I\'ve read a bunch of posts on adding header to UICollectionView. In an iOS 7+ app in Swift, I\'m trying to add a header with a UILabel in it whose height should adjust base

相关标签:
8条回答
  • 2020-12-08 05:54

    This is how I did it:

    let labels = [
    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ac lorem enim. Curabitur rhoncus efficitur quam, et pretium ipsum. Nam eu magna at velit sollicitudin fringilla nec nec nisi. Quisque nec enim et ipsum feugiat pretium. Vestibulum hendrerit arcu ut ipsum gravida, ut tincidunt justo pellentesque. Etiam lacus ligula, aliquet at lorem vel, ullamcorper commodo turpis. Nullam commodo sollicitudin mauris eu faucibus.",
    "Lorem ipsum dolor",
    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ac lorem enim. Curabitur rhoncus efficitur quam, et pretium ipsum. Nam eu magna at velit sollicitudin fringilla nec nec nisi. Quisque nec enim et ipsum feugiat pretium."]
    

    The basic idea is to create an identical UILabel to the one that will be shown in the section header. That label will be used to set the desired size for the header in the referenceSizeForHeaderInSection method.

    I have a label outlet called label in my UICollectionReusableView subclass (MyHeaderCollectionReusableView), which I use for my section header view by assigning it in the storyboard (setting "MyHeader" as Reuse Identifier for the section view). That mentioned label has the horizontal and vertical space constraints to the section header borders in order to autolayout correctly.

    override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
            return 3
        }
    
    override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
    
            let headerView =
            collectionView.dequeueReusableSupplementaryViewOfKind(kind,
                withReuseIdentifier: "MyHeader",
                forIndexPath: indexPath)
                as MyHeaderCollectionReusableView
    
            headerView.label.text = labels[indexPath.section]
    
            return headerView
    
        }
    
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
            // that -16 is because I have 8px for left and right spacing constraints for the label.
            let label:UILabel = UILabel(frame: CGRectMake(0, 0, collectionView.frame.width - 16, CGFloat.max))
            label.numberOfLines = 0
            label.lineBreakMode = NSLineBreakMode.ByWordWrapping
           //here, be sure you set the font type and size that matches the one set in the storyboard label
            label.font = UIFont(name: "Helvetica", size: 17.0)
            label.text = labels[section]
            label.sizeToFit()
    
    // Set some extra pixels for height due to the margins of the header section.  
    //This value should be the sum of the vertical spacing you set in the autolayout constraints for the label. + 16 worked for me as I have 8px for top and bottom constraints.
            return CGSize(width: collectionView.frame.width, height: label.frame.height + 16)
        }
    
    0 讨论(0)
  • 2020-12-08 05:54

    You have to implement the UICollectionViewDelegate method referenceSizeForHeaderInSection.

    There you have to calculate the height without using the label by calling boundingRectWithSize:options:context: on the string with the appropriate attributes.

    0 讨论(0)
提交回复
热议问题