Search code examples
iosswiftuicollectionviewnslayoutconstraintios-autolayout

How to adjust height of UICollectionView to be the height of the content size of the UICollectionView?


I would like the UICollectionView (The red one) to shrink to the height of the content size in this case UICollectionViewCells(the yellow ones) because there is a lot of empty space. What I tried is to use:

override func layoutSubviews() {
    super.layoutSubviews()
    if !__CGSizeEqualToSize(bounds.size, self.intrinsicContentSize) {
        self.invalidateIntrinsicContentSize()
    }
}

override var intrinsicContentSize: CGSize {
    return self.collection.contentSize
}

but return self.collection.contentSize always return (width, 0) and for this reason it shrinks too much to value of height 30 (The value which I set in the XIB file for the height, although I have constaint >= 30).

enter image description here


Solution

  • I would suggest the following:

    1. Add a height constraint to your collection view.
    2. Set its priority to 999.
    3. Set its constant to any value that makes it reasonably visible on the storyboard.
    4. Change the bottom equal constraint of the collection view to greater or equal.
    5. Connect the height constraint to an outlet.
    6. Every time you reload the data on the collection view do the following:

    You may also want to consider the Inset of the collection view by adding it to the content size.

    Code Sample:

    CGFloat height = myCollectionView.collectionViewLayout.collectionViewContentSize.height
    heightConstraint.constant = height
    self.view.setNeedsLayout() Or self.view.layoutIfNeeded()
    

    Explanation: Extra, You don't have to read if you understand it. obviously!!

    The UI will try to reflect all the constraints no matter what are their priorities. Since there is a height constraint with lower priority of (999), and a bottom constraint of type greater or equal. whenever, the height constraint constant is set to a value less than the parent view height the collection view will be equal to the given height, achieving both constraints.

    But, when the height constraint constant set to a value more than the parent view height both constraints can't be achieved. Therefore, only the constraint with the higher priority will be achieved which is the greater or equal bottom constraint.

    The following is just a guess from an experience. So, it achieves one constrant. But, it also tries to make the error in the resulted UI for the other un-achieved lower priority constraint as lowest as possible. Therefore, the collection view height will be equal to the parent view size.