39

I have a common UICollectionView with paging and all.

Still trying to figure out why on viewDidLoad:, viewWillAppear: and viewDidAppear: , only on first view call, I get the wrong size when calling myCollectionView.collectionView.contentSize.width. It always respond with 0 width (height is always correct). Successive reload of the view get me the correct one.

Resorted to using

self.collectionView.collectionViewLayout.collectionViewContentSize

which give me the correct width event on first load.

Still a mystery to me.

klauslanza
  • 671
  • 1
  • 6
  • 8

4 Answers4

71

So I was seeing a similar issue where contentSize width was always zero. The simple answer is...there is probably no content in the collectionView yet. That was why it's content size is zero.

I was also noticing that sometimes after calling invalidateLayout on my UICollectionView, I was seeing that self.collectionView.collectionViewLayout.collectionViewContentSize was not the same as self.collectionView.contentSize.

After much searching I found a great hint here in this SO post

What I needed to do to get both contentSize calculations to be the same was to call [self.collectionView layoutIfNeeded] immediately after calling [self.collectionView reloadData] or [self.collectionView.collectionViewLayout invalidateLayout].

This essentially forces the reload to happen immediately instead of on the next runloop cycle.

I really hope this solves your issue.

Community
  • 1
  • 1
ucangetit
  • 2,595
  • 27
  • 21
  • You saved my life. :D Thank you so so much. @ucangetit – iPeter May 31 '17 at 19:45
  • I find my collectionView.contentSize.height is larger than the max result of `contentOffset.y`, even with `[self.collectionView layoutIfNeeded]`. – wzso Mar 11 '19 at 08:41
  • 2
    this didn't work for me. I'm using `layout.estimatedItemSize = CGSize(width: 1, height: 1)` and it returns 1, 1 even after calling self.collectionView.layoutIfNeeded – osrl Mar 22 '19 at 10:59
  • 1
    @osrl make sure you set your `estimatedItemSize` close to your actual size of your cells. This property is just a starting point for the system to size your cells with, if your cells are all wildly different sizes, then it's best to start with a size of your smallest cell IMHO. – ucangetit Aug 25 '19 at 14:56
3

In my case, I was always getting content size zero. layoutIfNeeded() was not enough for me I have to get content size inside DispatchQueue.main.async ie

    self.collectionView.layoutIfNeeded()
    DispatchQueue.main.async {
        print(self.collectionView.contentSize) 
    }
Muhammad Ali
  • 587
  • 5
  • 9
0

Above answer is correct, but if you are adding the UICollectionViewController programmatically or with xib/storyboard, we have to take care about the scrollDirection of the UICollectionViewFlowLayout() for the UICollectionViewController. If it is horizontal and you want to track the content height, then there is a strong possibility that you will not get proper results.

In my case I used below code.

self.someCollectionViewController?.collectionView.reloadData()
self.someCollectionViewController?.collectionView.layoutIfNeeded()
if let height = self.someCollectionViewController?.collectionViewLayout.collectionViewContentSize.height {

   self.someProductCollectionViewHeightConstraints?.constant = height
}
Sanjay Mangaroliya
  • 4,286
  • 2
  • 29
  • 33
0

I got the same mistake ,and I resolve this by layout.estimatedItemSize = CGSizeMake(CGFLOAT_MIN, 24), height 24 is which I wanted height, the item's width is I want to auto calcullated