Анимируйте UIView с несколькими поворотами при переводе вверх и вниз - PullRequest
0 голосов
/ 19 июня 2019

У меня есть кнопка swirlButton, с которой я хотел бы анимировать прыжок вверх и вниз, и он должен был переворачиваться 3 раза вверх и 3 раза назад. Я использую TranslateBy, чтобы переместить его, и повернул, чтобы повернуть его, хотя в этом примере у меня есть только анимированная часть поворота, которая возвращается в обратном направлении после завершения анимации.

Прежде всего, я понятия не имею, как заставить его вращаться более одного раза. Например, я не могу установить повернутое (на :) значение на .pi * 3, потому что оно кажется равным 0 градусов и никогда не анимируется. То же самое, если я установлю его на .pi.

var transforms: CGAffineTransform = .identity

let jumpDuration:Double = 2.0 //0.8
let halfJumpDuration:Double = jumpDuration/2.0

UIView.animateKeyframes(withDuration: jumpDuration, delay: 0, options: [UIView.KeyframeAnimationOptions.calculationModeCubicPaced], animations: {

    UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: halfJumpDuration/jumpDuration, animations: {
        transforms = transforms.translatedBy(x: 0, y: -60)
        transforms = transforms.rotated(by: .pi/2)
        swirlButton.transform = transforms
    })

    UIView.addKeyframe(withRelativeStartTime: halfJumpDuration/jumpDuration, relativeDuration: halfJumpDuration/jumpDuration, animations: {
        transforms = .identity
        transforms = transforms.translatedBy(x: 0, y: 0)
        swirlButton.transform = transforms
    })

},
   completion: { _ in

        print("animation finished")

})

Помимо подъема и опускания, вращение очень далеко от того, что я хотел бы случиться. Сложно ли заставить его вращаться против часовой стрелки 3 раза вверх и продолжать вращаться против часовой стрелки 3 раза вниз?

1 Ответ

1 голос
/ 19 июня 2019

Я думаю, что для этого проще использовать CABasicAnimation.

Вот что я придумал:

func animateButton() {
  swirlButton.layer.add(rotateAnimation(), forKey: nil)

  CATransaction.begin()
  let upAnimation = bounceAnimation()
  CATransaction.setCompletionBlock{ () in
    self.swirlButton.layer.add(self.bounceAnimation(animatingDown: true), forKey: nil)
  }
  swirlButton.layer.add(upAnimation, forKey: nil)
  CATransaction.commit()
}

func rotateAnimation() -> CABasicAnimation {
  let rotate = CABasicAnimation(keyPath: "transform.rotation")
  rotate.fromValue = 0
  rotate.toValue = -6*CGFloat.pi
  rotate.duration = 2
  return rotate
}

func bounceAnimation(animatingDown: Bool = false) -> CABasicAnimation {
  let buttonY = swirlButton.layer.position.y
  let buttonX = swirlButton.layer.position.x
  let translate = CABasicAnimation(keyPath: "position")
  translate.fromValue = animatingDown ? [buttonX, buttonY - 200] : [buttonX, buttonY]
  translate.toValue = animatingDown ? [buttonX, buttonY] : [buttonX, buttonY - 200]
  translate.duration = 1
  translate.fillMode = .forwards
  translate.isRemovedOnCompletion = false
  return translate
}

translate.fillMode = .forwards & translate.isRemovedOnCompletion = false необходимо дляпредотвращение мерцания между анимациями, а CATransaction позволяет нам устанавливать блок завершения, когда заканчивается первая анимация (вверх).

...