UIbutton destellando animation

Me preguntaba si era posible aplicar una animation intermitente a un button UI. He buscado en internet pero solo he encontrado el código para una animation de pulso que cambia continuamente el tamaño de mi Uibutton. En su lugar, estaba pensando en algún tipo de animation intermitente para alertar al usuario que tiene que presionar el button. El único enfoque al problema que puedo pensar es cambiando el alfa constantemente usando:

[self setAlpha:0.5]; 

… pero no será tan visible como un button que parpadee.

Tal vez no sea la mejor manera, y realmente no le permite detener el flasheo … pero esto es simple, funciona y no obstaculiza la interacción del usuario:

 - (void)viewDidLoad { [self flashOn:myButton]; } - (void)flashOff:(UIView *)v { [UIView animateWithDuration:.05 delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^ { v.alpha = .01; //don't animate alpha to 0, otherwise you won't be able to interact with it } completion:^(BOOL finished) { [self flashOn:v]; }]; } - (void)flashOn:(UIView *)v { [UIView animateWithDuration:.05 delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^ { v.alpha = 1; } completion:^(BOOL finished) { [self flashOff:v]; }]; } 

Leyendo todas las respuestas hasta el momento encontré la siguiente solución. Repite varias veces y hace el trabajo por mí.

 CGFloat oldAlpha = v.alpha; CGFloat minAlpha = 0.2; enum UIViewAnimationOptions options = UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionAutoreverse | UIViewAnimationOptionCurveEaseInOut; [UIView animateWithDuration:.3 delay:0.3 options:options animations:^{ [UIView setAnimationRepeatCount:4]; v.alpha = minAlpha; } completion:^(BOOL finished) { v.alpha = oldAlpha; }]; 

Prueba esta:

Llame a este método cuando desee que parpadee / flash el button

 blinkTimer=[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(toggleButtonImage:) userInfo:nil repeats:YES]; 

y escribe este método

 - (void)toggleButtonImage:(NSTimer*)timer { if(toggle) { [blinkBtn setImage:[UIImage imageNamed:@"ButtonImage.png"] forState: UIControlStateNormal]; } else { [blinkBtn setImage:[UIImage imageNamed:@"ButtonImage1.png"] forState: UIControlStateNormal]; } toggle = !toggle; } 

en .h escribe esta

 NSTimer *blinkTimer; BOOL toggle; 

e invalida el timer en el que desea detener el parpadeo / parpadeo

 [blinkTimer invalidate]; 

Lo hice creando mi propio control, subclassando UIControl ya que Apple no recomienda atornillar con la jerarquía de vista de UIButton. Agrego una image de background que representa la image de background estándar del button y una image de image "shiny" sobre el background para representar el estado iluminado y alternar su opacidad para que sea pulso.

Además, alterno la opacidad de la sombra de la capa para que brille.

Inicializando el Código:

 - (void)TS_commonButtonInit { UIImage *shoutoutBackground = [UIImage imageNamed:@"root-navigation-bar-share-button"]; UIImage *shoutoutHighlightedBackground = [UIImage imageNamed:@"root-navigation-bar-share-button-highlighted"]; UIImage *shoutoutPulseImage = [UIImage imageNamed:@"root-navigation-bar-share-button-glowing"]; shoutoutBackground = [shoutoutBackground stretchableImageWithLeftCapWidth:7 topCapHeight:0]; shoutoutHighlightedBackground = [shoutoutHighlightedBackground stretchableImageWithLeftCapWidth:7 topCapHeight:0]; shoutoutPulseImage = [shoutoutPulseImage stretchableImageWithLeftCapWidth:7 topCapHeight:0]; [[self backgroundView] setImage:shoutoutBackground]; [[self backgroundView] setHighlightedImage:shoutoutHighlightedBackground]; [self setGlowingImage:shoutoutPulseImage]; [self setExclusiveTouch:YES]; [self addSubview:[self backgroundView]]; [self addSubview:[self glowingImageView]]; [[self layer] setShadowColor:[[UIColor colorWithHexString:@"ffc521" alpha:1] CGColor]]; [[self layer] setShadowOpacity:0]; [[self layer] setShadowRadius:5]; [[self layer] setShadowOffset:CGSizeMake(0, 0)]; [[self layer] setShadowPath:[[UIBezierPath bezierPathWithRoundedRect:[self bounds] cornerRadius:6] CGPath]]; } 

Código de pulsación:

 - (void)pulse:(NSInteger)numberOfTimes { CGFloat pulseLength = .8; [[self glowingImageView] setAlpha:0]; CABasicAnimation *pulseAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"]; [pulseAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; [pulseAnimation setDuration:pulseLength]; [pulseAnimation setRepeatCount:numberOfTimes]; [pulseAnimation setAutoreverses:YES]; [pulseAnimation setFromValue:@(0)]; [pulseAnimation setToValue:@(1)]; [pulseAnimation setRemovedOnCompletion:YES]; [[self layer] setShadowOpacity:0]; CABasicAnimation *shadowAnimation = [CABasicAnimation animationWithKeyPath:@"shadowOpacity"]; [shadowAnimation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; [shadowAnimation setDuration:pulseLength]; [shadowAnimation setRepeatCount:numberOfTimes]; [shadowAnimation setAutoreverses:YES]; [shadowAnimation setFromValue:@(0)]; [shadowAnimation setToValue:@(1)]; [shadowAnimation setRemovedOnCompletion:YES]; [[[self glowingImageView] layer] addAnimation:pulseAnimation forKey:@"opacity"]; [[self layer] addAnimation:shadowAnimation forKey:@"shadowOpacity"]; } 

Tal vez pueda tener dos files [botones] .png diferentes que giran en un ciclo, asignan la misma acción a ellos y hacen que esto comience siempre que se cumpla una determinada condición. Me gustaría escribir el código, pero es probable que esté lleno de errores. ¿Has probado algo así?