Анимация CAGradientLayer в Swift

Я пытаюсь анимировать CAGradientLayer с помощью Swift. Для ресурса я использую этот пост

Вот мой код

class ViewController: UIViewController {

  var gradient : CAGradientLayer?;

  override func viewDidLoad() {
    super.viewDidLoad()
  }

  override func viewDidAppear(animated: Bool) {

    self.gradient = CAGradientLayer()
    self.gradient?.frame = self.view.bounds
    self.gradient?.colors = [ UIColor.redColor().CGColor, UIColor.redColor().CGColor]
    self.view.layer.insertSublayer(self.gradient, atIndex: 0)

    animateLayer()
  }

  func animateLayer(){

    var fromColors = self.gradient?.colors
    var toColors: [AnyObject] = [ UIColor.blueColor().CGColor, UIColor.blueColor().CGColor]

    var animation : CABasicAnimation = CABasicAnimation(keyPath: "colors")

    animation.fromValue = fromColors
    animation.toValue = toColors
    animation.duration = 3.00
    animation.removedOnCompletion = true
    animation.fillMode = kCAFillModeForwards
    animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear)
    animation.delegate = self

    self.gradient?.addAnimation(animation, forKey:"animateGradient")
  }
}

Я попытался это сделать в Objective-C, и он работает, но мне нужно использовать его в Swift, и когда я запускаю программу, которую она оживляет, но возвращается к предыдущему цвету в конце, мне нужно, чтобы он оставался синим.

Ответы

Ответ 1

Я проверил ваш код и нашел здесь одну ошибку. Вы забыли установить цвет self.gradient, вы просто даете цвета анимации, поэтому анимация работает нормально, и в конце вы видите, что ее цвет возвращается к red.

Запишите этот недостающий код:

var toColors: [AnyObject] = [UIColor.blueColor().CGColor, UIColor.blueColor().CGColor]
self.gradient.colors = toColors // You missed this line
var animation : CABasicAnimation = CABasicAnimation(keyPath: "colors")

Вы также можете проверить рабочий код здесь: Пример

ОБНОВЛЕНИЕ: как я могу непрерывно повторять этот переход градиента?

Итак, вы можете использовать delegate для CAAnimation. Это даст вам знать, как только анимация будет закончена, и затем вы можете установить значение fromColors и toColors и вызвать функцию animateLayer() снова и снова. Но для этого вам придется внести несколько изменений в свой код.

  • Сделайте fromColors и toColors глобальным.
  • Измените их значение в методе делегата animationDidStop.
  • Вызвать функцию animateLayer() еще раз.

Вот тело метода delegate:

override func animationDidStop(anim: CAAnimation!, finished flag: Bool) {

    self.toColors = self.fromColors;
    self.fromColors = self.gradient?.colors
    animateLayer()
}

И вы также можете проверить рабочий код здесь: Пример

Ответ 2

Я попытался это сделать в Objective-C, и он работает, но мне нужно использовать его в Swift, и когда я запускаю программу, она оживляет, но возвращается к предыдущий цвет в конце, мне нужно, чтобы он оставался синим.

Вам нужно просто:

animation.removedOnCompletion = false // not true like in your code

Ответ 3

Для справок в будущем... Использование 100% CPU вызвано функцией animationDidStop. Он перезапускает анимацию, пока текущая анимация еще не закончена. Проверьте завершенный флаг:

override func animationDidStop(anim: CAAnimation, finished: Bool) {
    if finished {
        self.toColors = self.fromColors;
        self.fromColors = self.gradient?.colors

        animateLayer()
    }
}