UICollectionView header dynamic height using Auto Layout

后端 未结 5 1083
臣服心动
臣服心动 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 02:53

    Here's an elegant, up to date solution.

    As stated by others, first make sure that all you have constraints running from the very top of your header view to the top of the first subview, from the bottom of the first subview to the top of the second subview, etc, and from the bottom of the last subview to the bottom of your header view. Only then auto layout can know how to resize your view.

    The following code snipped returns the calculated size of your header view.

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    
        // Get the view for the first header
        let indexPath = IndexPath(row: 0, section: section)
        let headerView = self.collectionView(collectionView, viewForSupplementaryElementOfKind: UICollectionView.elementKindSectionHeader, at: indexPath)
    
        // Use this view to calculate the optimal size based on the collection view's width
        return headerView.systemLayoutSizeFitting(CGSize(width: collectionView.frame.width, height: UIView.layoutFittingExpandedSize.height),
                                                  withHorizontalFittingPriority: .required, // Width is fixed
                                                  verticalFittingPriority: .fittingSizeLevel) // Height can be as large as needed
    }
    

    Edit

    As @Caio noticed in the comments, this solution will cause a crash on iOS 10 and older. In my project, I've "solved" this by wrapping the code above in if #available(iOS 11.0, *) { ... } and providing a fixed size in the else clause. That's not ideal, but acceptable in my case.

提交回复
热议问题