Shake Animation for UITextField/UIView in Swift Shake Animation for UITextField/UIView in Swift swift swift

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)