2
votes

I'm trying to implement UICollectionView (flowLayout) with self sizing items.

Implementation is very simple - I have just set estimatedItemSize and set UICollectionViewCell constraints to manage it's size.

Everything works fine at first data reload after collectionView was created, but on another or some other reload few items at the top becomes same size as estimatedItemSize is. If scroll down and up - items size looks good again.

I have spend 2 days with this issue experimenting different cell constraints, trying to setNeedsLayout in various places and other stuff around collectionView. Is it bug?

1

1 Answers

1
votes

In this post I had an interesting problem that I found my own answer to. There are two important functions to be using properly for the sizing purposes which are:

minimumInteritemSpacingForSectionAtIndex
insetForSectionAtIndex
sizeForItemAtIndexPath

Example of me using them in Swift

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionView, minimumInteritemSpacingForSectionAtIndex section: Int) -> CGFloat {
    return 0
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
    return UIEdgeInsetsMake(0, 0, 0, 0)
}

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize {
    let screenRect: CGRect = collectionView.bounds
    let screenWidth: CGFloat = screenRect.size.width
    let cellWidth: CGFloat = screenWidth / 24
    //Replace the divisor with the column count requirement. Make sure to have it in float.
    let size: CGSize = CGSize(width: cellWidth, height: cellWidth)
    return size
}

The biggest secret is to be careful about attaching your views to the trailing edge and the bottom layout. If you only attach them to leading and the top, then you can set the width and height programmatically through frame or constraints. I think that doing it through constraints is a little more straight forward, though in my personal project I have chose to do it the other way because it makes the functionality slightly cleaner in my opinion.

Try to accomplish as much of a cells layout as possible inside of cellForItemAt.