Как я мог сделать эту анимацию в UICollectionViewCell при нажатии?

Я пытаюсь сделать аналогичную анимацию, которая делает эти UICollectionViewCell при выборе одного из них. Я имею в виду то, что они делают, как будто они встают, но нюх, как добраться до него. Я явно должен сделать в методе:

CollectionView ( CollectionView : UICollectionView , didSelectItemAtIndexPath indexPath : NSIndexPath ) 

Я оставляю видео на YouTube, в котором показано, что я говорю https://www.youtube.com/watch?v=gFWiyOERVBg

Спасибо


person Miguel Perez    schedule 29.03.2016    source источник
comment
посмотрите это, как только это поможет вам я настраиваю состояние выбора моего подкласса uicollectionviewcell"> stackoverflow.com/questions/13657883/   -  person Anbu.Karthik    schedule 29.03.2016


Ответы (3)


DidSelectItemAtIndexPath может использоваться в качестве триггера, но в остальном здесь не имеет значения.

Если бы я попытался воспроизвести это, я бы выбрал следующий подход:

Во-первых, воздействуют на все ячейки в представлении коллекции, извлекают массив видимых элементов и применяют преобразование к каждому.

Преобразование выглядит так, как будто оно происходит в 2 этапа: сначала преобразование вращения по оси Y со значением, применяемым к матрице преобразования в .m34 для изменения перспективы. Во-вторых, преобразование перевода с отрицательным значением x, достаточно большим, чтобы переместить ячейку за пределы экрана. Поместите эти преобразования в группу базовой анимации, и я подозреваю, что вы будете очень близки к желаемому эффекту.

Последнее наблюдение заключается в том, что это похоже на переход, поэтому вы, вероятно, можете добиться этого как часть UIViewControllerAnimation.

ИЗМЕНИТЬ

Сегодня утром у меня было немного времени, поэтому я собрал для вас код.

Присмотревшись к анимации, я заметил, что движение влево на самом деле было частью анимации вращения с точкой привязки, установленной на 0 по оси x. Таким образом, все, что нам нужно, это анимация вращения и затухания — все центрируется на x = 0.

Чтобы добиться этого, самый простой подход — добавить CALayer для каждой из ячеек в списке коллекции и анимировать добавленный слой, как только ячейка будет «привита» к новому слою.

  - (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 -

Есть несколько вещей, которые вам нужно изменить, чтобы это выглядело точно так же, как анимация в вашем видео:

  1. Рандомизируйте массив, содержащий список видимых элементов. Как бы то ни было, элементы будут срабатывать последовательно или в соответствии с массивом видимых элементов.
  2. Рандомизируйте продолжительность анимации группы или, как минимум, введите небольшую задержку между анимациями (рандомизация продолжительности от 0,35 (время по умолчанию Apple) до, скажем, 0,6 должно работать хорошо).
  3. Возможно, рандомизируйте угол анимации вращения - должно работать что-то между, скажем, 50 и 85 градусами (в настоящее время установлено значение 65 в приведенном выше примере);

Вот и все... Наслаждайтесь!

person MDB983    schedule 29.03.2016
comment
Да, я думаю, это ключ. Я попробую и , хотя я новичок в анимации, не знаю, смогу ли я получить. Спасибо - person Miguel Perez; 29.03.2016
comment
Спасибо за такое подробное объяснение. Мне удалось реализовать это с помощью Swift. Переход получился точно как на видео. - person Bharath V N; 29.11.2016

Вы можете получить UICollectionViewCell, используя эту строку внутри didSelectItemAtIndexPath,

let cell = collectionView.cellForItemAtIndexPath(indexPath)

С помощью ссылки на ячейку вы можете анимировать с помощью animateWithDuration или любого другого метода для анимации объектов внутри ячейки.

person Ulysses    schedule 29.03.2016
comment
Да, я это знаю, мой конкретный вопрос заключается в том, как сделать анимацию видео, любая анимация, которую я знаю, делает это. Спасибо за Ваш ответ - person Miguel Perez; 29.03.2016
comment
Хм, я не уверен, что именно в ней используется анимация, но взгляните на этот урок, в нем много информации по этому вопросу, objc.io/issues/12-animations/collectionview-animations - person Ulysses; 29.03.2016

Я перевожу быстрый ответ MDB983, если он кому-то поможет.

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")
 }
person Miguel Perez    schedule 31.03.2016