UICollectionView with self-sizing cells resizes cells during insert/remove animation
I ran into this, and it took me a while to figure out that the size it was reverting to was the estimated size.
I think I figured out a workaround:
- Keep one instance of your self-sizing cell class around
- Implement
sizeForItemAtIndexPath
, and configure that cell instance with data for that index path, then ask it for its preferred size (systemLayoutFittingSize
). - Cache this information in a dictionary for performance.
See example project here.
Set
estimatedItemSize
property to some appropriate size.In your custom
UICollectionView
class override below method and cache layoutAttributes's size given by super.-(UICollectionViewLayoutAttributes*)preferredLayoutAttributesFittingAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes{ UICollectionViewLayoutAttributes * superAttr = [super preferredLayoutAttributesFittingAttributes:layoutAttributes]; //Cache size which is returned by super (superAttr.frame.size) since super calculates the correct size for auto size cells. return superAttr;}
3.In sizeForItemAtIndexPath return cached size if available else estimated size.
-(CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { //return cached size if available else the estimated size}
To avoid cell resize use InvalidationContext
let context = UICollectionViewFlowLayoutInvalidationContext() context.invalidateFlowLayoutAttributes = false collectionView.collectionViewLayout.invalidateLayout(with: context) UIView.animate(withDuration: 0.3) { self.collectionView.layoutIfNeeded() }