动画UITextField以指示错误的密码

JAH*_*lia 29 iphone core-animation objective-c ios

如何添加动画来UITextField指示错误的密码,就像Facebook应用程序(登录屏幕)或Mac OS X登录框中的密码一样?

先感谢您.

Kai*_*ann 43

这样的事情

-(void)shake:(UIView *)theOneYouWannaShake
{
  [UIView animateWithDuration:0.03 animations:^
                                  {
                                    theOneYouWannaShake.transform = CGAffineTransformMakeTranslation(5*direction, 0);
                                  } 
                                  completion:^(BOOL finished) 
                                  {
                                    if(shakes >= 10)
                                    {
                                      theOneYouWannaShake.transform = CGAffineTransformIdentity;
                                      return;
                                    }
                                    shakes++;
                                    direction = direction * -1;
                                    [self shake:theOneYouWannaShake];
                                  }];
}
Run Code Online (Sandbox Code Playgroud)

所以你还需要三个东西:在摇动被称为int shakes之前设置为1的int方向,在调用抖动之前设置为0,以及一个大小如你所愿的常量MAX_SHAKES.希望有所帮助.

编辑:

这样叫:

  direction = 1;
  shakes = 0;
  [self shake:aUIView];
Run Code Online (Sandbox Code Playgroud)

里面的头文件添加

int direction;
int shakes;
Run Code Online (Sandbox Code Playgroud)


Dic*_*ngh 13

(2015年1月16日)更新:(枚举UIViewAnimationOptions)强制转换并且UIViewAnimationOptionCurveEaseOut在typedef NS_OPTIONS(NSUInteger,UIViewAnimationOptions)下每个UIView.h为2 << 16

(2013年1月31日)进一步修改Kai的答案包括:

  1. 边缘延迟0.01s
  2. easeInOut
  3. 减少每次震动的震动持续时间从0.09到0.04
  4. 每1个完整循环(右 - 右 - 右)通过pt减少运动

注意:如果您打算一起摇动两个控件(电子邮件和密码),您可能希望避免使用类或静态变量进行抖动和翻译.相反,初始化并传递抖动并作为参数进行转换.我使用静态因此不需要类变量.

-(void)shakeAnimation:(UIView*) view {
    const int reset = 5;
    const int maxShakes = 6;

    //pass these as variables instead of statics or class variables if shaking two controls simultaneously
    static int shakes = 0;
    static int translate = reset;

    [UIView animateWithDuration:0.09-(shakes*.01) // reduce duration every shake from .09 to .04 
                          delay:0.01f//edge wait delay
                        options:(enum UIViewAnimationOptions) UIViewAnimationCurveEaseInOut
                     animations:^{view.transform = CGAffineTransformMakeTranslation(translate, 0);}
                     completion:^(BOOL finished){
                         if(shakes < maxShakes){
                             shakes++;

                             //throttle down movement
                             if (translate>0)
                                 translate--;

                             //change direction
                             translate*=-1;
                             [self shakeAnimation:view];
                         } else {
                             view.transform = CGAffineTransformIdentity;
                             shakes = 0;//ready for next time
                             translate = reset;//ready for next time
                             return;
                         }
                     }];
}
Run Code Online (Sandbox Code Playgroud)

  • `(enum UIViewAnimationOptions)UIViewAnimationCurveEaseInOut`是一个错误,将被翻译为`UIViewAnimationOptionLayoutSubviews`.你应该传递`UIViewAnimationOptionCurveEaseInOut`,它是预期的`UIViewAnimationOptions`类型. (2认同)

Cra*_*lot 9

这个Swift 2.0答案不需要递归,也不需要循环.只需CABasicAnimation通过改进这个SO答案来利用:

func shakeView(shakeView: UIView) {
    let shake = CABasicAnimation(keyPath: "position")
    let xDelta = CGFloat(5)
    shake.duration = 0.15
    shake.repeatCount = 2
    shake.autoreverses = true

    let from_point = CGPointMake(shakeView.center.x - xDelta, shakeView.center.y)
    let from_value = NSValue(CGPoint: from_point)

    let to_point = CGPointMake(shakeView.center.x + xDelta, shakeView.center.y)
    let to_value = NSValue(CGPoint: to_point)

    shake.fromValue = from_value
    shake.toValue = to_value
    shake.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    shakeView.layer.addAnimation(shake, forKey: "position")
}
Run Code Online (Sandbox Code Playgroud)

针对Swift 4进行了更新:

func shakeView(_ shakeView: UIView) {
    let shake = CABasicAnimation(keyPath: "position")
    let xDelta = CGFloat(5)
    shake.duration = 0.15
    shake.repeatCount = 2
    shake.autoreverses = true

    let from_point = CGPoint(x: shakeView.center.x - xDelta, y: shakeView.center.y)
    let from_value = NSValue(cgPoint: from_point)

    let to_point = CGPoint(x: shakeView.center.x + xDelta, y: shakeView.center.y)
    let to_value = NSValue(cgPoint: to_point)

    shake.fromValue = from_value
    shake.toValue = to_value
    shake.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    shakeView.layer.add(shake, forKey: "position")
}
Run Code Online (Sandbox Code Playgroud)


小智 6

基于以前的答案作为快速方法准备使用:

func shakeTextField (textField : UITextField, numberOfShakes : Int, direction: CGFloat, maxShakes : Int) {

    let interval : NSTimeInterval = 0.03

    UIView.animateWithDuration(interval, animations: { () -> Void in
        textField.transform = CGAffineTransformMakeTranslation(5 * direction, 0)

        }, completion: { (aBool :Bool) -> Void in

            if (numberOfShakes >= maxShakes) {
                textField.transform = CGAffineTransformIdentity
                textField.becomeFirstResponder()
                return
            }

            self.shakeTextField(textField, numberOfShakes: numberOfShakes + 1, direction: direction * -1, maxShakes: maxShakes)

    })

}
Run Code Online (Sandbox Code Playgroud)

打电话给它:

shakeTextField(aTextField,numberOfShakes:0, direction :1, maxShakes : 10)
Run Code Online (Sandbox Code Playgroud)