Shake Animation for UITextField/UIView in Swift
You can change the duration
and repeatCount
and tweak it. This is what I use in my code. Varying the fromValue
and toValue
will vary the distance moved in the shake.
let animation = CABasicAnimation(keyPath: "position")animation.duration = 0.07animation.repeatCount = 4animation.autoreverses = trueanimation.fromValue = NSValue(cgPoint: CGPoint(x: viewToShake.center.x - 10, y: viewToShake.center.y))animation.toValue = NSValue(cgPoint: CGPoint(x: viewToShake.center.x + 10, y: viewToShake.center.y))viewToShake.layer.add(animation, forKey: "position")
The following function is used in any view.
extension UIView { func shake() { let animation = CAKeyframeAnimation(keyPath: "transform.translation.x") animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) animation.duration = 0.6 animation.values = [-20.0, 20.0, -20.0, 20.0, -10.0, 10.0, -5.0, 5.0, 0.0 ] layer.add(animation, forKey: "shake") }}
EDIT: using CABasicAnimation
cause the app to crash if you ever trigger the animation twice in a row. So be sure to use CAKeyframeAnimation
. Bug has been fixed, thanks to the comments :)
Or you can use this if you want more parameters (in swift 5) :
public extension UIView { func shake(count : Float = 4,for duration : TimeInterval = 0.5,withTranslation translation : Float = 5) { let animation = CAKeyframeAnimation(keyPath: "transform.translation.x") animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear) animation.repeatCount = count animation.duration = duration/TimeInterval(animation.repeatCount) animation.autoreverses = true animation.values = [translation, -translation] layer.add(animation, forKey: "shake") } }
You can call this function on any UIView, UIButton, UILabel, UITextView etc. This way
yourView.shake()
Or this way if you want to add some custom parameters to the animation:
yourView.shake(count: 5, for: 1.5, withTranslation: 10)