UICollectionView vertical scroll with cells for self-calibration displays only half of the cells

I installed UICollectionView (with default layout and vertical scrolling) with custom cells loaded from xib. Cells contain a pair of elements (a UILabel and a UIView ) with restrictions on them. I set limits so that the cell height increases as the height of the label text increases using the new UICollectionViewFlowLayout property available in iOS8, estimatedItemSize :

 layout.estimatedItemSize = CGSizeMake(self.collectionView.frame.width, 100) 

Everything works like a charm, except for one big problem: UICollectionView loads only half of the elements returned by the numberOfItemsInSection method. So, when a method returns, say, 10, my UICollectionView displays only 5 cells (but displays and displays them perfectly).

Some results of my debugging attempts:

  • I was able to force the remaining elements to be loaded by calling invalidateLayout or changing the number of partitions from 1 to 2. But this is just debugging the hacks.
  • Separately, everything works like a charm when I replace the estimatedItemSize itemSize property, i.e. hard-coded element size. But it defeats the self-separation functionality that I would like to implement.

I guess something is wrong with how I think about cells of the very size. In particular, I am wondering if the problem is related to limitations.

I would appreciate any help here.

+7
ios ios8 swift uicollectionview uicollectionviewcell
source share
4 answers

I believe this is due to a bug in iOS8 that still exists with iOS8.3.

Views of the stream layout collection with self-sized cells will not be able to display part of their contents if estimatedItemSize too small. This is despite the fact that according to the API docs, the only requirement for estimatedItemSize is that it is non-zero to trigger self-size behavior.

Only Apple can fix this. I think that the best solution to the problem in the medium term is to inflate the value of the ITemSize`.

This repo demonstrates the problem: https://github.com/algal/SelfSizingCellsDemo . (I filed the radar at rdar: // 18078598.)

+3
source share

The obvious non-hacky solution is to implement

 flowLayout.collectionView(layout:sizeForItemAtIndexPath:) 

but of course this is more code than you probably hoped for.

I suggest you try two more things:

  • Try experimenting with more likely estimated sizes. Also try the default, CGSizeZero .
  • Check what happens in preferredlLayoutAttributesFittingAttributes() by examining the layoutAttributes parameter. You may find a clue as to why other cells are being squeezed out.
+2
source share

In a custom subclass of UICollectionViewFlowLayout

override prepareLayout as follows:

 - (void)prepareLayout { [super prepareLayout]; CGSize contentSize = self.collectionView.contentSize; // Without this line, the scrolling doesn't go all the way to the bottom, right away but takes a while [super layoutAttributesForElementsInRect:CGRectMake(0.0f, 0.0f, contentSize.width, contentSize.height)]; } 
+1
source share

I had the same problem. I used layout.estimatedItemSize = CGSizeMake(373.0, 500.0) along with

 preferredLayoutAttributesFittingAttributes( layoutAttributes: UICollectionViewLayoutAttributes) -> UICollectionViewLayoutAttributes! 

and I got exactly what I wanted, but I received only half of the displayed cells. Curiously, when I changed the valuItemSize property to: layout.estimatedItemSize = view.bounds.size ALL cells appear !! Hope this helps. Good luck.

0
source share

All Articles