I'm writing a custom UICollectionViewFlowLayout
and I've noticed that initialLayoutAttributesForAppearingItemAtIndexPath:
and initialLayoutAttributesForAppearingDecorationElementOfKind:atIndexPath:
will be called for all sections when I invoke performBatchUpdates:completion:
on the collection view. The result is that all sections have the animation applied to them instead of just the newly added section.
[collectionView performBatchUpdates:^{
currentModelArrayIndex++;
[collectionView insertSections:[NSIndexSet indexSetWithIndex:currentModelArrayIndex]];
[collectionView reloadSections:[NSIndexSet indexSetWithIndex:currentModelArrayIndex-1]];
} completion:^(BOOL finished) {
[collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:currentModelArrayIndex] atScrollPosition:UICollectionViewScrollPositionTop animated:YES];
}];
What I've tried so far is removing the call to performBatchUpdates:completion:
in lieu of simple updates, but the already existing sections (all of them) are animated in anyway. I've come up with a solution of checking to make sure that I'm changing the layout attributes of only the last section, but it feels hacky.
if (decorationIndexPath.section == [(id<UICollectionViewDataSource>)self.collectionView.delegate numberOfSectionsInCollectionView:self.collectionView] - 1)
{
layoutAttributes.alpha = 0.0f;
layoutAttributes.transform3D = CATransform3DMakeTranslation(-CGRectGetWidth(layoutAttributes.frame), 0, 0);
}
Is this the proper way to go about animating only some sections?
OK, I've got an answer; it's not a lot prettier than the previous one, but it keeps the layout from touching the datasource, so it's cleaner.
Basically, we need to override
prepareForCollectionViewUpdates:
andfinalizeCollectionViewUpdates
to keep track of the sections that we're inserting. I have a mutable set that containsNSNumber
instances of the sections that we're inserting.Next, I check to see if the index path's section is included in that set when setting the initial layout attributes for items and decoration views.
I'm returning
nil
from these methods otherwise becausenil
is the default value.This has the added benefit of having nicer rotation animations, as well.