Advanced UICollectionView animation using invalidateLayout calls
The UICollectionView Programming Guide says:
In addition to animating insertions, deletions, and move operations, you can invalidate the layout at any time and force it to redraw its contents. Invalidating the layout does not animate items directly; when you invalidate the layout, the collection view displays the items in their newly calculated positions without animating. However, the act of invalidating the layout causes the layout object to move items explicitly. In a custom layout, you might use this behavior to position cells at regular intervals and create an animated effect.
I've been trying something like this, where AnimationStep
is an enum used by my UICollectionViewFlowLayout
subclass to conditionally set the positions of tiles with a three stage animation:
-(void)update{
[self animateLayoutAfterDelay:2.0 toStep:AnimationStepOne];
[self animateLayoutAfterDelay:4.0 toStep:AnimationStepTwo];
[self animateLayoutAfterDelay:6.0 toStep:AnimationStepThree];
}
-(void)animateLayoutAfterDelay:(NSTimeInterval)delay toStep:(MagazineLayoutAnimationStep)step {
double delayInSeconds = delay;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[UIView animateWithDuration:2.0 animations:^{
self.layout.animationStep = step;
[self.layout invalidateLayout];
}];
});
}
This has quite unpredictable effects. Some cells animate in the way I'd expect, some get hidden and shown or just appear in their new locations. I put random background colours on the cells to see if this might be the effect of UICollectionView recycling cells and sure enough, sometimes it was. Which explains some of the weirdness, but not all of it.
Does anybody know how Apple want me to animate cells and move them around?
(I need this because my collection view cells tend to change size and I want a graceful animation without any diagonal movement).
答案是使用中间布局。
[self.collectionView setCollectionViewLayout: layoutForStepOne animated:YES completion:^(BOOL finished) {
[self.collectionView setCollectionViewLayout: layoutForStepTwo animated:YES completion:^(BOOL finished) {
[self.collectionView setCollectionViewLayout: layoutForStepThree animated:YES];
}];
}];
It is simple:
Create a new instance of some UICollectionViewLayout and use
- (void)setCollectionViewLayout:(UICollectionViewLayout *)layout animated:(BOOL)animated
to set the layout on your UICollectionView to this new layout object. Make sure you use YES for the animated parameter.
Edit: For doing multi staged animation i would try
performBatchUpdates:completion:
and put the next update into the completion block and repeat.
链接地址: http://www.djcxy.com/p/84160.html