1

I 'm trying to do a similar animation which make these UICollectionViewCell when you select one. I mean the fact they do as if they get up , but nose how to get to get it . I clearly should be done in the method :

CollectionView ( CollectionView : UICollectionView , didSelectItemAtIndexPath indexPath : NSIndexPath ) 

I leave a YouTube video which it shows what I say https://www.youtube.com/watch?v=gFWiyOERVBg

Thanks

  • see this once it helps you http://stackoverflow.com/questions/13657883/how-can-i-customize-the-selection-state-of-my-uicollectionviewcell-subclass – Anbu.Karthik Mar 29 '16 at 11:43

3 Answers3

2

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:

  1. 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.
  2. 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).
  3. 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!

MDB983
  • 2,444
  • 17
  • 20
  • Yes, I think that's the key. I'll try and , although I am a rookie with the animations do not know if I can get. Thank you – Miguel Perez Mar 29 '16 at 17:05
  • Thanks for such a detailed explanation. I managed to implement it using swift. The transition came out exactly as in the video. – Bharath V N Nov 29 '16 at 05:12
1

You can get the UICollectionViewCell using this line inside the didSelectItemAtIndexPath,

let cell = collectionView.cellForItemAtIndexPath(indexPath)

With the cell reference, you can animate with animateWithDuration, or any other method to animate the objects inside the cell.

Ulysses
  • 2,281
  • 1
  • 16
  • 24
  • Yes, I know that , my specific question is how to do the animation of the video , any animation I know do it. Thanks for your answer – Miguel Perez Mar 29 '16 at 11:35
  • Hum, I am not sure with animation exactly it uses, but take a look at this tutorial, it have a lot of insights about the subject, https://www.objc.io/issues/12-animations/collectionview-animations/ – Ulysses Mar 29 '16 at 11:43
1

I trasnslate to swift the MDB983 response if it would serve someone

func processVisibleItems(){
    let visibleItems = self.collectionView?.indexPathsForVisibleItems()
    for p in visibleItems! as [NSIndexPath]{
        // create a layer which will contain the cell for each of the visibleItems
        let containerLayer = CALayer()
        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
        var containerFrame:CGRect! = containerLayer.frame
        containerFrame.origin.x -= containerLayer.frame.size.width/2
        containerLayer.frame = containerFrame
        containerLayer.anchorPoint = CGPointMake(0.0, 0.5)
        self.collectionView?.layer.addSublayer(containerLayer)

        //add the cell to the new layer 
        let cell = self.collectionView?.cellForItemAtIndexPath(p) as! NewspaperImageCollectionViewCell
        cell.frame = containerLayer .convertRect(cell.frame, fromLayer: cell.superview!.layer)
        containerLayer.addSublayer(cell.layer)
        addAnimationForLayer(containerLayer)
     }
}

func addAnimationForLayer(layerToAnimate: CALayer){
    // fade-out animation
    let fadeOutAnimation = CABasicAnimation(keyPath: "opacity")
    fadeOutAnimation.toValue = 0.0

    //rotation Animation
    let rotationAnimation = CABasicAnimation(keyPath: "transform")
    var tfm = CATransform3D()
    tfm = CATransform3DMakeRotation((65.0 * CGFloat(M_PI) )/180.0, 0.0, -1.0, 0.0)
    tfm.m14 = -0.002
    rotationAnimation.fromValue = NSValue(CATransform3D:CATransform3DIdentity)
    rotationAnimation.toValue = NSValue(CATransform3D:tfm)

    //group the animations and add to the new layer
    let group = CAAnimationGroup()
    group.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
    group.fillMode = kCAFillModeForwards
    group.removedOnCompletion = false
    group.duration = 0.35
    group.animations = [rotationAnimation,fadeOutAnimation]
    layerToAnimate.addAnimation(group, forKey: "rotateAndFadeAnimation")
 }