Задержка CAKeyframeAnimation перед повторением
У меня есть анимация CAKeyframeAnimation
, которую я хотел бы повторить навсегда, используя repeatCount = HUGE_VALF
. Продолжительность анимации составляет 2 секунды, но я хотел бы иметь паузу в 3 секунды перед каждым циклом.
Только два способа, которые я могу сделать, это:
-
Сделайте всю анимацию за последние 5 секунд и добавьте дополнительные keyTimes и значения, чтобы получить паузу, которую я ищу в течение последних 3 секунд анимации 5s. Это выглядит немного хаки.
-
Повторяйте анимацию только один раз, а затем добавьте что-то вроде performSelector:afterDelay:2
, чтобы снова запустить анимацию и т.д. и т.д. Это также грязно. Также будет означать, что мне нужно называть addAnimation:
каждые 5 секунд, что я не уверен, что это оптимально с точки зрения производительности.
Есть ли еще один вариант, который может отсутствовать? Является ли один из этих двух методов лучше, чем другой?
Ответы
Ответ 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:
-
Начать
yourUiComponent.applyPulse()
-
Прекратить
yourUiComponent.applyPulse (ложь)