I've created a heart beat animation for a UIButton. However, there is no way to stop this animation as it's an endless code loop. After tinkering with numerous UIView animation code blocks I've been unable to get UIViewAnimationOptions.Repeat
to produce what I need. If I could do that I could simply button.layer.removeAllAnimations()
to remove the animations. What is a way to write this that allows for removal of the animation? I'm thinking a timer possibly but that could be kind of messy with multiple animations going on.
func heartBeatAnimation(button: UIButton) {
button.userInteractionEnabled = true
button.enabled = true
func animation1() {
UIView.animateWithDuration(0.5, delay: 0.0, options: [], animations: { () -> Void in
button.transform = CGAffineTransformMakeScale(2.0, 2.0)
button.transform = CGAffineTransformIdentity
}, completion: nil)
UIView.animateWithDuration(0.5, delay: 0.5, options: [], animations: { () -> Void in
button.transform = CGAffineTransformMakeScale(2.0, 2.0)
button.transform = CGAffineTransformIdentity
}) { (Bool) -> Void in
delay(2.0, closure: { () -> () in
animation2()
})
}
}
func animation2() {
UIView.animateWithDuration(0.5, delay: 0.0, options: [], animations: { () -> Void in
button.transform = CGAffineTransformMakeScale(2.0, 2.0)
button.transform = CGAffineTransformIdentity
}, completion: nil)
UIView.animateWithDuration(0.5, delay: 0.5, options: [], animations: { () -> Void in
button.transform = CGAffineTransformMakeScale(2.0, 2.0)
button.transform = CGAffineTransformIdentity
}) { (Bool) -> Void in
delay(2.0, closure: { () -> () in
animation1()
})
}
}
animation1()
}
This works perfectly. The damping and spring need to be tweaked a little bit but this solves the problem. removeAllAnimations()
clears the animation and returns the button to it's normal state.
button.userInteractionEnabled = true
button.enabled = true
let pulse1 = CASpringAnimation(keyPath: "transform.scale")
pulse1.duration = 0.6
pulse1.fromValue = 1.0
pulse1.toValue = 1.12
pulse1.autoreverses = true
pulse1.repeatCount = 1
pulse1.initialVelocity = 0.5
pulse1.damping = 0.8
let animationGroup = CAAnimationGroup()
animationGroup.duration = 2.7
animationGroup.repeatCount = 1000
animationGroup.animations = [pulse1]
button.layer.addAnimation(animationGroup, forKey: "pulse")
This post was very helpful: CAKeyframeAnimation delay before repeating
Swift 5 code, works without the pause between pulses:
let pulse = CASpringAnimation(keyPath: "transform.scale")
pulse.duration = 0.4
pulse.fromValue = 1.0
pulse.toValue = 1.12
pulse.autoreverses = true
pulse.repeatCount = .infinity
pulse.initialVelocity = 0.5
pulse.damping = 0.8
switchButton.layer.add(pulse, forKey: nil)
I created something like this:
let animation = CAKeyframeAnimation(keyPath: "transform.scale")
animation.values = [1.0, 1.2, 1.0]
animation.keyTimes = [0, 0.5, 1]
animation.duration = 1.0
animation.repeatCount = Float.infinity
layer.add(animation, forKey: "pulse")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With