Search code examples
iosswiftuicollectionviewautolayout

How to dynamically change the height of UICollectionView to adapt to content size


I have two collection views in the same view and I would like to reduce the height of them, so that they adapt to the content size. However, the height should only reduce and never increase more than the initial value set in the storyboard. How can I accomplish this?

So far I have tried changing the collectionView height from the height costraint outlet everytime I would add new data but I don't get the right result. I tried changing it with this code:

self.deadlineCollectionViewHeight.constant = deadlinesCollectionView.collectionViewLayout.collectionViewContentSize.height

expected behaviour Wrong result


Solution

  • At what point are you trying to read the collectionViewContentSize value?

    If you are doing that right after a reloadData() call - that might not give you accurate results because these calls are deferred to be executed at some point on main thread. The content size won't change immediately after doing the reloadData() call.

    Try following :

    1. Declare a variable inside the class like this.
    private var contentSizeObservation: NSKeyValueObservation?
    
    1. Start observing contentSize changes.
    contentSizeObservation = deadlinesCollectionView.observe(\.contentSize, options: .new, changeHandler: { [weak self] (cv, _) in
        guard let self = self else { return }
        self.deadlineCollectionViewHeight.constant = cv.collectionViewLayout.collectionViewContentSize.height
    })
    
    1. Do NOT Forget to clean this up in deinit call -
    deinit {
        contentSizeObservation?.invalidate()
    }
    

    This approach will make sure that your collectionView is always as big in height as it's content.