2011-02-17 13 views
14

Estoy tratando de animar el color del texto en un UILabel a pulso de: [Negro] a [Blanco] a [Negro] y repita.¿Animar a UILabel pulsante?

- (void)timerFlash:(NSTimer *)timer { 
[[self navTitle] setTextColor:[[UIColor whiteColor] colorWithAlphaComponent:0.0]]; 
[UIView animateWithDuration:1 
         delay:0 
        options:UIViewAnimationOptionAllowUserInteraction 
       animations:^{[[self navTitle] setTextColor:[[UIColor whiteColor] colorWithAlphaComponent:1.0]];} 
       completion:nil]; 
} 

.

[self setFadeTimer:[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerFlash:) userInfo:nil repeats:YES]]; 

En primer lugar no estoy seguro de mi método, mi plan (como se puede ver arriba) fue la creación de un bloque de animación y llamarlo usando un NSTimer repitiendo hasta que se cancele.

Mi segundo problema (como puede ver arriba) es que estoy animando desde negro (alfa 0) a blanco (alfa 1) pero no sé cómo animar de nuevo a negro para que la animación gire a la perfección

Esencialmente, lo que quiero es el color del texto para pulsar en un UILabel hasta que el usuario presiona un botón para continuar.

EDIT_001:

me estaba metiendo en problemas porque no se puede animar [UILabel setColor:] Sin embargo, puede animada [UILabel setAlpha:] por lo que me va a dar que un ir.

EDIT_002:

- (void)timerFlash:(NSTimer *)timer { 
    [[self navTitle] setAlpha:0.5]; 
    [UIView animateWithDuration:2 
          delay:0 
         options:UIViewAnimationOptionAllowUserInteraction 
        animations:^{[[self navTitle] setAlpha:0.9];} 
        completion:nil]; 
} 

Esto funciona (Por cierto: yo quiero que pare por lo que me enganchó hasta un NSTimer para que pueda cancelar esa) la única cosa es que esto anima a midGray a nearWhite y luego vuelve a aparecer. ¿Alguien sabe cómo animaría desde cerca de White a MidGray para que tenga un buen ciclo sin problemas? enter image description here

EDIT_003: (Solución)

El código sugerido por Dave DeLong (véase más adelante) no funciona cuando de hecho modificado para utilizar el atributo de estilo opacidad CALayer:

UILabel *navTitle; 
@property(nonatomic, retain) UILabel *navTitle; 

.

// ADD ANIMATION 
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"opacity"]; 
[anim setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; 
[anim setFromValue:[NSNumber numberWithFloat:0.5]]; 
[anim setToValue:[NSNumber numberWithFloat:1.0]]; 
[anim setAutoreverses:YES]; 
[anim setDuration:0.5]; 
[[[self navTitle] layer] addAnimation:anim forKey:@"flash"]; 

.

// REMOVE ANIMATION 
[[[self navTitle] layer] removeAnimationForKey:@"flash"]; 
+0

No estoy 100% convencido de que animateWithDuration trabaja con NSTimer como pueda No conseguirá hacer otra cosa que no sea pop de un color al siguiente sin animación. – fuzzygoat

Respuesta

15

Probablemente pueda hacer esto con un CAAnimation. Acabo de lanzar un pequeño proyecto de demostración que hice hace un tiempo en github. Muestra el logotipo olímpico y hace que los anillos vuelen a una ubicación aleatoria en la pantalla y luego vuelvan a su posición original. Podría probablemente hacer algo muy similar, pero obviamente no utilizar la propiedad position.

Aquí está el código básico para hacer uno de los anillos de volar alrededor:

CABasicAnimation * a = [CABasicAnimation animationWithKeyPath:@"position"]; 
[a setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]]; 
[a setFromValue:[NSValue valueWithCGPoint:[layer position]]]; 
[a setToValue:[NSValue valueWithCGPoint:[self randomPoint]]]; 
[a setAutoreverses:YES]; 
[a setDuration:1.0]; 
[layer addAnimation:a forKey:nil]; 

Su fromValue y toValue valores serían CGColorRefs, y su ruta de acceso clave de animación sería diferente, pero el truco aquí es el setAutoreverses:YES. Esto animará desde el fromValue hasta el toValue, y luego de vuelta al fromValue. Es bastante práctico.:)

https://github.com/davedelong/Demos/blob/master/OlympicRings


Si eso no funciona (y que no), entonces sólo podría superponer dos UILabels en la parte superior de la otra y animar a sus valores alfa de 0,0 a 1,0 (o viceversa) al mismo tiempo.

+0

Gracias Dave, voy a echar un vistazo, también creo que la propiedad textColor de UILabel no es animable, que tal vez sea la razón por la que todo lo que puedo obtener es una aparición muy no animada. – fuzzygoat

+0

Hola, no estoy tan familiarizado con CoreAnimation, por lo que puedo ver, el mejor valor de keyPath sería "opacidad", aunque no puedo encontrar una opacidad directa en UILabel o UIView, podría tener que probar "alfa", pero no estoy seguro de cómo va a funcionar eso. [a setFromValue: [[self navTitle] setAlpha: 0.9]]; No estoy en mi computadora de trabajo en este momento, lo intentaré más tarde ... – fuzzygoat

9

Si lo que desea que suceda de forma indefinida, puede utilizar la respuesta de Dave DeLong, o esto:

[UIView animateWithDuration:1 
         delay:0 
        options:UIViewAnimationOptionAllowUserInteraction | 
          UIViewAnimationOptionAutoreverse | 
          UIViewAnimationOptionRepeat 
       animations:^{[[self navTitle] setTextColor:[UIColor whiteColor]];} 
       completion:nil]; 

La ventaja de usar CAAnimation, por supuesto, es que se puede eliminar la animación más adelante; con esto, para detenerlo tendrías que profundizar en el CALayer y encontrar la animación para detenerlo.

Usted sugirió, sin embargo, que UILabel.textColor podría no ser animable. Esa es una posibilidad. Si es así, puede usar esta misma técnica para hacer la transición entre dos UILabels de los diferentes colores y simplemente desvanecer sus valores alfa.

+0

Gracias BJ, quiero que se detenga, por lo que lo enganché a un NSTimer, así que puedo matar el temporizador cuando haya terminado. Interesantes opciones, sin embargo, haré una nota para futuras referencias. – fuzzygoat

1

(igual que aquí Cancel block in UIView animateWithDuration)

acabo de repetir la animación y mato después de algún tiempo con un bloque de despacho:

- (void)animate // Blink a view three times 
{ 
    // We need to stop the animation after a while (0.9 sec) 
    dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0.9 * NSEC_PER_SEC); 
    dispatch_after(popTime, dispatch_get_main_queue(), ^(void) 
    { 
     [view.layer removeAllAnimations]; 
     view.alpha = 0.0; // Animation clean-up 
    }); 

    [UIView animateWithDuration:0.15 // 0.15*6=0.9: It will animate six times (three in reverse) 
          delay:0.0 
         options:UIViewAnimationOptionAutoreverse | UIViewAnimationOptionRepeat 
        animations:^{ 
         view.alpha = 1.0; // Animation 
        } 
        completion:NULL]; 
}