iosobjective-canimationuicollectionviewsupplementary

Animating a UICollectionView supplementary view resize


I am using the CSStickyHeaderFlowLayout from https://github.com/jamztang/CSStickyHeaderFlowLayout

and as part of my app I have in the header view/cell a button that sends to the collection view that it needs to grow. in turn the collection view changes the header preferred size in the CSStickyHeaderFlowLayout and sends a invalidateLayout to the CSStickyHeaderFlowLayout. trying to animate via the anime block does not work well as it moves the header from the button to top. It makes it really odd thing. is there a way for the flowLayout to animate changes in supplementary view properly?

this is my code to change the size.

- (void)treckDetailMapCellSizeToggle:(BOOL)toggle {
    //Modifier l'attribu de la map et invalider le layout pour le redessiner.
    CSStickyHeaderFlowLayout *layout = (id)self.collectionViewLayout;
    if ([layout isKindOfClass:[CSStickyHeaderFlowLayout class]]) {
        [UIView animateWithDuration:0.5 animations: ^{
            if (isMapCellExpended) {
                isMapCellExpended = NO;
                layout.parallaxHeaderReferenceSize = CGSizeMake(self.view.frame.size.width, HEADER_VIEW_PREFERED_SIZE);
            }
            else {
                isMapCellExpended = YES;
                layout.parallaxHeaderReferenceSize = CGSizeMake(self.view.frame.size.width, HEADER_VIEW_MAX_SIZE);
            }

            [layout invalidateLayout];
        }];
    }
}

This is a video of what goes on, as I tap the button called "Ajouter a la carte".

https://www.youtube.com/watch?v=aqm99HebvwE

Edit:

thaks to reading this page (that I had not seen before). I found out that this will make it a bit better but not fix the problem. :

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    CSStickyHeaderFlowLayout *layout = (id)self.collectionViewLayout;

    if ([layout isKindOfClass:[CSStickyHeaderFlowLayout class]]) {
        [self.collectionView performBatchUpdates: ^{
            preferedSize = preferedSize == 200 ? 300 : 200;
            layout.parallaxHeaderReferenceSize = CGSizeMake(self.view.frame.size.width, preferedSize);
        } completion: ^(BOOL finished) {
        }];

    }
}

Solution

  • To animate the size change invalidate the layout within a view animation closure. The size itself should be set through the appropriate layout delegate method e.g. collectionView(collectionView:collectionViewLayout:referenceSizeForHeaderInSection:)

    UIView.animate(withDuration: 0.33) {
      self.collectionView.collectionViewLayout.invalidateLayout()
    }