Agite la animation para UITextField / UIView en Swift

Estoy tratando de averiguar cómo hacer que el text Field shake on button presione cuando el usuario deja el campo de text en blanco.

Actualmente tengo el siguiente código trabajando:

if self.subTotalAmountData.text == "" { let alertController = UIAlertController(title: "Title", message: "What is the Sub-Total!", prefernetworkingStyle: UIAlertControllerStyle.Alert) alertController.addAction(UIAlertAction(title: "Okay", style: UIAlertActionStyle.Default,handler: nil)) self.presentViewController(alertController, animated: true, completion: nil) } else { } 

Pero creo que sería mucho más atractivo simplemente hacer que el campo de text se agite como una alerta.

No puedo encontrar nada para animar el campo de text.

¿Algunas ideas?

¡Gracias!

Puede cambiar la duration y repeatCount y modificarlo. Esto es lo que uso en mi código. La fromValue toValue fromValue y toValue variará la distancia recorrida en el movimiento.

 let animation = CABasicAnimation(keyPath: "position") animation.duration = 0.07 animation.repeatCount = 4 animation.autoreverses = true animation.fromValue = NSValue(CGPoint: CGPointMake(txtField.center.x - 10, txtField.center.y)) animation.toValue = NSValue(CGPoint: CGPointMake(txtField.center.x + 10, txtField.center.y)) txtField.layer.addAnimation(animation, forKey: "position") 

La siguiente function se usa en cualquier vista.

 extension UIView { func shake() { let animation = CAKeyframeAnimation(keyPath: "transform.translation.x") animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) 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") } } 

O puede usar esto si desea más parameters ( en swift 3 ):

 public extension UIView { func shake(count : Float? = nil,for duration : TimeInterval? = nil,withTranslation translation : Float? = nil) { // You can change these values, so that you won't have to write a long function let defaultRepeatCount = 4 let defaultTotalDuration = 0.5 let defaultTranslation = -5 let animation : CABasicAnimation = CABasicAnimation(keyPath: "transform.translation.x") animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) animation.repeatCount = count ?? defaultRepeatCount animation.duration = (duration ?? defaultTotalDuration)/TimeInterval(animation.repeatCount) animation.autoreverses = true animation.byValue = translation ?? defaultTranslation layer.add(animation, forKey: "shake") } } 

Puede llamar a esta function en cualquier UIView, UIButton, UILabel, UITextView, etc. De esta manera

 yourView.shake() 

O de esta forma, si desea agregar algunos parameters personalizados a la animation:

 yourView.shake(count: 5, for: 1.5, withTranslation: 10) 

Swift 3.0

 extension UIView { func shake(){ let animation = CABasicAnimation(keyPath: "position") animation.duration = 0.07 animation.repeatCount = 3 animation.autoreverses = true animation.fromValue = NSValue(cgPoint: CGPoint(x: self.center.x - 10, y: self.center.y)) animation.toValue = NSValue(cgPoint: CGPoint(x: self.center.x + 10, y: self.center.y)) self.layer.add(animation, forKey: "position") } } 
 extension CALayer { func shake(duration: NSTimeInterval = NSTimeInterval(0.5)) { let animationKey = "shake" removeAnimationForKey(animationKey) let kAnimation = CAKeyframeAnimation(keyPath: "transform.translation.x") kAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) kAnimation.duration = duration var needOffset = CGRectGetWidth(frame) * 0.15, values = [CGFloat]() let minOffset = needOffset * 0.1 repeat { values.append(-needOffset) values.append(needOffset) needOffset *= 0.5 } while needOffset > minOffset values.append(0) kAnimation.values = values addAnimation(kAnimation, forKey: animationKey) } } 

Cómo utilizar:

 [UIView, UILabel, UITextField, UIButton & etc].layer.shake(NSTimeInterval(0.7)) 

Esto se basa en CABasicAnimation, también contiene un efecto de audio:

 extension UIView{ var audioPlayer = AVAudioPlayer() func vibrate(){ let animation = CABasicAnimation(keyPath: "position") animation.duration = 0.05 animation.repeatCount = 5 animation.autoreverses = true animation.fromValue = NSValue(CGPoint: CGPointMake(self.center.x - 5.0, self.center.y)) animation.toValue = NSValue(CGPoint: CGPointMake(self.center.x + 5.0, self.center.y)) self.layer.addAnimation(animation, forKey: "position") // audio part do { audioPlayer = try AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(mySoundFileName, ofType: "mp3")!)) audioPlayer.prepareToPlay() audioPlayer.play() } catch { print("∙ Error playing vibrate sound..") } } }