The didSelectItemAtIndexPath may be used as a trigger but otherwise is irrelevant here.
If I were to try to reproduce this, I would take the following approach:
Firstly, all cells in the collection view are being effected, retrieve an array of visible items and apply a transform to each.
The transform looks as though it's happening in 2 stages, first a y axis rotation transform with a value applied to the transform matrix at .m34 to change perspective. Secondly, a translate transform with a negative x value sufficiently large to move the cell off screen. Put these transforms in a basic animation group and I suspect you'll be very close to the desired effect.
The final observation is that this appears to be a transition, so you can probably achieve this as part of UIViewControllerAnimation.
EDIT
I had some time this morning so I put some code together for you.
On taking a closer look at the animation I noticed that the move to the left was in fact part of the rotation animation, with the anchor point set to 0 on the x-axis. So effectively all we need is a rotation and fade animation - all centered on x = 0.
To accomplish this, the simplest approach is to add a CALayer for each of the Cells in the collection list and animate the added layer once the cell had been "grafted" to the new layer.
- (void)processVisibleItems{
NSArray *visibleItems = [self.collectionView indexPathsForVisibleItems];
for (NSIndexPath *p in visibleItems) {
// create a layer which will contain the cell for each of the visibleItems
CALayer *containerLayer = [CALayer layer];
containerLayer.frame = self.collectionView.layer.bounds;
containerLayer.backgroundColor = [UIColor clearColor].CGColor;
// we need to change the anchor point which will offset the layer - adjust accordingly
CGRect containerFrame = containerLayer.frame;
containerFrame.origin.x -= containerLayer.frame.size.width/2;
containerLayer.frame = containerFrame;
containerLayer.anchorPoint = CGPointMake(0.0f, 0.5f);
[self.collectionView.layer addSublayer:containerLayer];
//add the cell to the new layer - change MyCollectionViewCell to your cell's class
MyCollectionViewCell *cell = (MyCollectionViewCell*)[self.collectionView cellForItemAtIndexPath:p];
cell.frame = [containerLayer convertRect:cell.frame fromLayer:cell.superview.layer];
[containerLayer addSublayer:cell.layer];
//add the animation to the layer
[self addAnimationForLayer:containerLayer];
}
}
- (void)addAnimationForLayer:(CALayer*)layerToAnimate{
// fade-out animation
CABasicAnimation *fadeOutAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
[fadeOutAnimation setToValue:@0.0];
//rotation Animation
CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
CATransform3D tfm = CATransform3DMakeRotation((65.0f * M_PI) / 180.0f, 0.0f, -1.0f, 0.0f);
//add perspective - change to your liking
tfm.m14 = -0.002f;
rotationAnimation.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
rotationAnimation.toValue = [NSValue valueWithCATransform3D:tfm];
//group the animations and add to the new layer
CAAnimationGroup *group = [CAAnimationGroup animation];
group.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
group.fillMode = kCAFillModeForwards;
group.removedOnCompletion = NO;
group.duration = 0.35f;
[group setAnimations:@[rotationAnimation, fadeOutAnimation]];
[layerToAnimate addAnimation:group forKey:@"rotateAndFadeAnimation"];
}
//To trigger on cell click simply call [self processVisibleItems] in didSelectItemAtIndexPath
NB -
There are a couple of things you'll need to change to get this looking exactly like the animation in your video:
- Randomize the array containing the list of visible items. As it stands, the items will trigger sequentially or as per the array of visible items.
- Randomize the Duration of the Group animation, or at a minimum, introduce a small delay between animations (randomizing the duration between 0.35 (Apple's default timing) and say 0.6 should work well).
- Possibly randomize the angle of the rotation animation - anything between say 50 and 85 degrees should work (currently set to 65 in the example above);
That's all there is to it.... Enjoy!