verificar puedo password incorrecta iforgot exchange enviaron demasiados crear contraseña codigos apple iphone objective-c ios core-animation

iphone - puedo - animando UITextField para indicar una contraseña incorrecta



no puedo verificar mi id de apple (12)

¿Cómo puedo agregar una animación a un UITextField para indicar una contraseña incorrecta exactamente como la de la aplicación de Facebook (en la pantalla de inicio de sesión) o el cuadro de inicio de sesión de Mac OS X?

gracias de antemano.


(16 de enero de 2015) Actualización: (enumeración UIViewAnimationOptions) cast está bien y UIViewAnimationOptionCurveEaseOut es 2 << 16 por UIView.h bajo typedef NS_OPTIONS (NSUInteger, UIViewAnimationOptions)

(31 de enero de 2013) Se modificó la respuesta de Kai para incluir:

  1. demora de borde de 0.01s
  2. EasyInOut
  3. reducir la duración de los batidos de cada batido de 0.09 a 0.04
  4. movimiento de aceleración hacia abajo por un pt cada 1 bucle completo (derecha-izquierda-derecha)

Nota: si planea agitar dos controles (correo electrónico y contraseña) juntos, es posible que desee evitar el uso de variables de clase o estáticas para agitar y traducir. En su lugar, inicialice y pase shake y traduzca como parámetros. Utilicé estadísticas, por lo que no se necesitan variables de clase

-(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; } }]; }


Algo como eso

-(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]; }]; }

Así que necesitas tres cosas más: una dirección int que se establece en 1 antes de que la vibración se llame int shakes, que se establece en 0 antes de que se llame la vibración y una constante MAX_SHAKES que sea tan grande como quieras. Espero que ayude.

EDITAR:

llámalo así:

direction = 1; shakes = 0; [self shake:aUIView];

dentro del archivo de cabecera agregar

int direction; int shakes;


Aquí está mi giro en él:

@implementation UITextField (Shake) - (void)shake { [self shakeWithIterations:0 direction:1 size:4]; } #pragma mark - Private - (void)shakeWithIterations:(int)iterations direction:(int)direction size:(int)size { [UIView animateWithDuration:0.09-(iterations*.01) animations:^{ self.transform = CGAffineTransformMakeTranslation(size*direction, 0); } completion:^(BOOL finished) { if (iterations >= 5 || size <= 0) { self.transform = CGAffineTransformIdentity; return; } [self shakeWithIterations:iterations+1 direction:direction*-1 size:MAX(0, size-1)]; }]; } @end


Aquí hay una Biblioteca Swift para animar Textfield en github. Simplemente importe el archivo swift y aplíquelo de la siguiente manera

// Shake with the default speed self.textField.shake(10, delta:5) //10 no. of shakes with 5 points wide // Shake with a custom speed self.sampleText.shake(10, delta: 5, speed: 0.10) //10 no. of shakes with 5 points wide in 100ms per shake


Basado en una respuesta previa como método rápido listo para usar:

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: ) }) }

Para llamarlo:

shakeTextField(aTextField,numberOfShakes:0, direction :1, maxShakes : 10)


Dado que la pregunta era sobre Objective-C, y como uso Objective-C en mi proyecto, creo que esta traducción de Objective-C de esta respuesta Swift anterior podría ser útil para otra persona:

- (void)shakeView:(UIView*)view { CABasicAnimation *shake = [CABasicAnimation animationWithKeyPath:@"position"]; CGFloat xDelta = 5.0; shake.duration = 0.15; shake.repeatCount = 2; shake.autoreverses = YES; CGPoint fromPoint = CGPointMake(view.center.x - xDelta, view.center.y); CGPoint toPoint = CGPointMake(view.center.x + xDelta, view.center.y); shake.fromValue = [NSValue valueWithCGPoint:fromPoint]; shake.toValue = [NSValue valueWithCGPoint:toPoint]; shake.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; [view.layer addAnimation:shake forKey:@"position"]; }


Esta respuesta Swift 2.0 no requiere recursión ni bucles. Solo aprovecha CABasicAnimation al refinar esta respuesta 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") }

Actualizado para 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") }


Probé la solución @stefreak pero el enfoque de bucle no funciona en iOS 7.1. Así que combiné las soluciones de @stefreak y @Chris, y añadí el bloque de finalización para recibir una notificación cuando finalice el temblor. Aquí está mi código:

- (void)shakeView:(UIView *)view iterations:(NSInteger)iterations direction:(NSInteger)direction completion:(void (^)())completion { const NSInteger MAX_SHAKES = 6; const CGFloat SHAKE_DURATION = 0.05; const CGFloat SHAKE_TRANSFORM = 10.0; [UIView animateWithDuration:SHAKE_DURATION delay:0.0 options:UIViewAnimationOptionCurveEaseIn animations:^{ view.transform = iterations >= MAX_SHAKES ? CGAffineTransformIdentity : CGAffineTransformMakeTranslation(SHAKE_TRANSFORM * direction, 0); } completion:^(BOOL finished) { if (finished) { if (iterations >= MAX_SHAKES) { if (completion) { completion(); } } else { [self shakeView:view iterations:(iterations + 1) direction:(direction * -1) completion:completion]; } } }]; } - (void)shakeView:(UIView *)view completion:(void (^)())completion { [self shakeView:view iterations:0 direction:1 completion:completion]; }


Si vino aquí buscando una respuesta MonoTouch, aquí hay una traducción aproximada del código de Dickey :

public static void /*Harlem*/Shake (this UIView view, int shakes = 6, int translation = 5) { UIView.Animate (0.03 + (shakes * 0.01), 0.01, UIViewAnimationOptions.CurveEaseInOut, () => { view.Transform = CGAffineTransform.MakeTranslation (translation, 0); }, () => { if (shakes == 0) { view.Transform = CGAffineTransform.MakeIdentity (); return; } if (translation > 0) translation --; translation *= -1; shakes --; Shake (view, shakes, translation); }); }

Ponlo con el resto de tus métodos de extensiones y llama así:

password.Shake ();


También puedes hacerlo utilizando animación básica.

let animation = CABasicAnimation(keyPath: "position") animation.duration = 0.09 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")

Aquí puede cambiar la duration , repeatCount conteo repeatCount Cambiando en el fromValue y el toValue va a cambiar la distancia movida en la sacudida


Swift 3 y stack_view instaed textField

func shakeTextField (stack_view : UIStackView, numberOfShakes : Int, direction: CGFloat, maxShakes : Int) { let interval : TimeInterval = 0.05 UIView.animate(withDuration: interval, animations: { () -> Void in stack_view.transform = CGAffineTransform(translationX: 5 * direction, y: 0) }, completion: { (aBool :Bool) -> Void in if (numberOfShakes >= maxShakes) { stack_view.becomeFirstResponder() return } self.shakeTextField(stack_view: stack_view, numberOfShakes: numberOfShakes + 1, direction: direction * -1, maxShakes: maxShakes ) }) }


Creé un método de categoría para UIView que se puede usar para sacudir cualquier elemento, por ejemplo, un Campo de campo de UIT, con la capacidad de recibir una notificación después de que finalice el temblor. Aquí está cómo usarlo:

[myPasswordField shake]; // Or with a callback after the shake [myPasswordField shakeWithCallback:^{ NSLog(@"Shaking has ended"); }];

Aquí está el código.

UIView + Shake.h

#import <UIKit/UIKit.h> @interface UIView (UIView_Shake) -(void)shake; -(void)shakeWithCallback:(void (^)(void))completeBlock; @end

UIView + Shake.m

#import "UIView+Shake.h" #import <objc/runtime.h> @implementation UIView (UIView_Shake) static void *NumCurrentShakesKey; static void *NumTotalShakesKey; static void *ShakeDirectionKey; - (int)numCurrentShakes { return [objc_getAssociatedObject(self, &NumCurrentShakesKey) intValue]; } - (void)setNumCurrentShakes:(int)value { objc_setAssociatedObject(self, &NumCurrentShakesKey, [NSNumber numberWithInt:value], OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (int)numTotalShakes { return [objc_getAssociatedObject(self, &NumTotalShakesKey) intValue]; } - (void)setNumTotalShakes:(int)value { objc_setAssociatedObject(self, &NumTotalShakesKey, [NSNumber numberWithInt:value], OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (int)shakeDirection { return [objc_getAssociatedObject(self, &ShakeDirectionKey) intValue]; } - (void)setShakeDirection:(int)value { objc_setAssociatedObject(self, &ShakeDirectionKey, [NSNumber numberWithInt:value], OBJC_ASSOCIATION_RETAIN_NONATOMIC); } -(void)shake { [self shakeNextWithCompleteBlock:nil]; } -(void)shakeWithCallback:(void (^)(void))completeBlock { self.numCurrentShakes = 0; self.numTotalShakes = 6; self.shakeDirection = 8; [self shakeNextWithCompleteBlock:completeBlock]; } -(void)shakeNextWithCompleteBlock:(void (^)(void))completeBlock { UIView* viewToShake = self; [UIView animateWithDuration:0.08 animations:^ { viewToShake.transform = CGAffineTransformMakeTranslation(self.shakeDirection, 0); } completion:^(BOOL finished) { if(self.numCurrentShakes >= self.numTotalShakes) { viewToShake.transform = CGAffineTransformIdentity; if(completeBlock != nil) { completeBlock(); } return; } self.numCurrentShakes++; self.shakeDirection = self.shakeDirection * -1; [self shakeNextWithCompleteBlock:completeBlock]; }]; } @end