Подтвердить что ты не робот

Задержка CAKeyframeAnimation перед повторением

У меня есть анимация CAKeyframeAnimation, которую я хотел бы повторить навсегда, используя repeatCount = HUGE_VALF. Продолжительность анимации составляет 2 секунды, но я хотел бы иметь паузу в 3 секунды перед каждым циклом.

Только два способа, которые я могу сделать, это:

  • Сделайте всю анимацию за последние 5 секунд и добавьте дополнительные keyTimes и значения, чтобы получить паузу, которую я ищу в течение последних 3 секунд анимации 5s. Это выглядит немного хаки.

  • Повторяйте анимацию только один раз, а затем добавьте что-то вроде performSelector:afterDelay:2, чтобы снова запустить анимацию и т.д. и т.д. Это также грязно. Также будет означать, что мне нужно называть addAnimation: каждые 5 секунд, что я не уверен, что это оптимально с точки зрения производительности.

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

4b9b3361

Ответ 1

Отбрасывая анимацию Apple MKUserLocationView, я смог увидеть, как они это делают. Оказывается, это то, для чего CAAnimationGroup. Инкапсулируя анимацию в 2 секунды в 5-секундную группу анимации, вы получите 2-секундную анимацию, за которой следует 3-секундная задержка:

CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.duration = 5;
animationGroup.repeatCount = INFINITY;

CAMediaTimingFunction *easeOut = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

CABasicAnimation *pulseAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale.xy"];
pulseAnimation.fromValue = @0.0;
pulseAnimation.toValue = @1.0;
pulseAnimation.duration = 2;
pulseAnimation.timingFunction = easeOut;

animationGroup.animations = @[pulseAnimation];

[ringImageView.layer addAnimation:animationGroup forKey:@"pulse"];

Ответ 2

ответ samvermette в Swift 3:

let animationGroup = CAAnimationGroup()
animationGroup.duration = 5;
animationGroup.repeatCount = .infinity

let easeOut = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)

let pulseAnimation = CABasicAnimation(keyPath: "transform.scale.xy")
pulseAnimation.fromValue = 0
pulseAnimation.toValue = 1.0
pulseAnimation.duration = 2
pulseAnimation.timingFunction = easeOut

animationGroup.animations = [pulseAnimation]

ringImageView.layer.add(animationGroup, forKey: "pulse")

Ответ 3

Проверено на Swift 4.2

Просто внедрите следующее расширение, и тогда вы сможете получить хорошую импульсную анимацию на любом компоненте пользовательского интерфейса.

//MARK:- Pulse animation
extension UIView {

    func applyPulse(_ apply: Bool = true) {
        if apply {
            let animation = CABasicAnimation(keyPath: "transform.scale")
            animation.toValue = 1.5
            animation.duration = 0.8
            animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut)
            animation.autoreverses = true
            animation.repeatCount = Float.infinity
            self.layer.add(animation, forKey: "pulsing")
        } else {
            self.layer.removeAnimation(forKey: "pulsing")
        }
    }
}

Usase:

  1. Начать

    yourUiComponent.applyPulse()

  2. Прекратить

    yourUiComponent.applyPulse (ложь)