2010-10-15 27 views
19

Tengo una etiqueta que aparece mostrando los puntos en mi aplicación. Estoy usando el siguiente código para hacer que la etiqueta se agrande en escala, luego más pequeña. También me gustaría animar el cambio de color de púrpura a verde. ¿Puede alguien señalarme un recurso para lograr esto?iPad: Animate UILabels cambio de color

mLabel.textColor = [UIColor purpleColor]; 

[UIView beginAnimations:nil context:NULL]; 
[UIView setAnimationDuration:1.0]; 
[UIView setAnimationDelegate:self]; 
mLabel.transform = CGAffineTransformMakeScale(1.5,1.5); 
[UIView setAnimationRepeatCount:1]; 
mLabel.transform = CGAffineTransformMakeScale(0.5,0.5); 
mLabel.textColor = [UIColor greenColor]; 
[UIView commitAnimations]; 

Respuesta

26

Por desgracia, el color no se animan con animaciones UIView. Las respuestas a this question brindan algunas buenas soluciones sin usar Core Animation.

Si no les importa usar un CATextLayer en lugar de un UILabel, entonces el color (y la escala en su ejemplo) puede ser animado como esto:

#import <QuartzCore/QuartzCore.h> 
//Also need to add QuartzCore framework to project (as well as the import). 
// 
-(void)animateTextLayer { 

CGFloat animationDuration = 5; 

CATextLayer *textLayer = [CATextLayer layer]; 
[textLayer setString:@"Hello World"]; 
[textLayer setForegroundColor:[UIColor purpleColor].CGColor]; 
[textLayer setFontSize:30]; 
[textLayer setFrame:CGRectMake(20, 200, 300, 40)]; 
[[self.view layer] addSublayer:textLayer]; 

CABasicAnimation *colorAnimation = [CABasicAnimation 
            animationWithKeyPath:@"foregroundColor"]; 
colorAnimation.duration = animationDuration; 
colorAnimation.fillMode = kCAFillModeForwards; 
colorAnimation.removedOnCompletion = NO; 
colorAnimation.fromValue = (id)[UIColor purpleColor].CGColor; 
colorAnimation.toValue = (id)[UIColor greenColor].CGColor; 
colorAnimation.timingFunction = [CAMediaTimingFunction 
           functionWithName:kCAMediaTimingFunctionLinear]; 

CAKeyframeAnimation *scaleAnimation = [CAKeyframeAnimation 
             animationWithKeyPath:@"transform"]; 
NSArray *scaleValues = [NSArray arrayWithObjects: 
    [NSValue valueWithCATransform3D:CATransform3DScale(textLayer.transform, 1, 1, 1)], 
    [NSValue valueWithCATransform3D:CATransform3DScale(textLayer.transform, 1.5, 1.5, 1)], 
    [NSValue valueWithCATransform3D:CATransform3DScale(textLayer.transform, 0.5, 0.5, 1)], nil]; 
[scaleAnimation setValues:scaleValues]; 
scaleAnimation.fillMode = kCAFillModeForwards; 
scaleAnimation.removedOnCompletion = NO; 

CAAnimationGroup *animationGroup = [CAAnimationGroup animation]; 
animationGroup.duration = animationDuration; 
animationGroup.timingFunction = [CAMediaTimingFunction 
           functionWithName:kCAMediaTimingFunctionLinear]; 
animationGroup.fillMode = kCAFillModeForwards; 
animationGroup.removedOnCompletion = NO; 
animationGroup.animations = 
     [NSArray arrayWithObjects:colorAnimation, scaleAnimation, nil]; 

[textLayer addAnimation:animationGroup forKey:@"animateColorAndScale"]; 
} 
+0

aunque sólo habría una manera de establecer una alineación vertical en CATextLayer – bioffe

+4

He aquí una _mucho_ mejor solución utilizando sólo el propio UILabel el original: http: // stackoverflow .com/questions/6442774/is-uilabels-backgroundcolor-not-animatable/6442868 # 6442868 – Anna

+2

@AnnaKarenina El enlace que apuntó es para animar el color de fondo. – xhan

0

Añadir esto antes de su llamada a commitAnimations:

[UIView setAnimationTransition:UIViewAnimationTransitionNone forView:mLabel cache:YES]; 
6

La razón de que no es textColor animatable es que UILabel usa un CALayer regular en lugar de un CATextLayer.

Para hacer textColor animable (así como texto, fuente, etc.) podemos subclase UILabel y hacer que use un CATextLayer.

Este es un buen montón de trabajo, pero por suerte yo ya hice :-)

puede encontrar una explicación completa + una gota en el reemplazo de código abierto para UILabel en este article

67

Puede utilizar el método de vista de la transición de iOS 4.0 para hacer esto:

[UIView transitionWithView:statusLabel duration:0.25 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ 
    [statusLabel setTextColor:[UIColor whiteColor]]; 
    [statusLabel setShadowColor:[UIColor blackColor]]; 
} completion:nil]; 
+0

¡Guau! ¡Esto es excelente! ¡Gracias por compartir esto! Perdón por las exclamaciones, pero estaba a punto de crear una subclase de CATextLayer. – RileyE

+0

Este es un excelente consejo. La respuesta aceptada es probablemente más correcta desde el punto de vista técnico, pero este método logra el mismo efecto. Muchas gracias. – LeffelMania

+0

Correcto. Usar una 'CATextLayer' es la respuesta más correcta ya que interpolará los valores de color entre los colores from y to.Sin embargo, esto es útil cuando una transición de fundido cruzado básico de un color a otro es suficiente. – LucasTizma

1

Si es necesario utilizar colores IB que se especifican para los estados resaltados o seleccionadas y desea animar el cambio de color con efecto de fundido se puede utilizar junto código :

Swift:

@IBAction func buttonAction(sender: AnyObject) { 

    // Set selected to leave same color as for highlighted 
    // (default=black, highlighted=red, selected=red) 
    self.openAllButton.selected = true 

    // Delay before the color change animation 
    let delayInSeconds = 0.1; 
    let delay = delayInSeconds * Double(NSEC_PER_SEC) 
    let popTime = dispatch_time(DISPATCH_TIME_NOW, Int64(delay)); 
    dispatch_after(popTime, dispatch_get_main_queue(), { 
     // Animate color change 
     UIView.transitionWithView(self.openAllButton, duration: 1.0, options: UIViewAnimationOptions.TransitionCrossDissolve, animations: {() -> Void in 
      self.openAllButton.selected = false   // selected->default 
      }) { (v:Bool) -> Void in 
     } 
    }); 

}

0

Prueba esto:

[UIView animateWithDuration:0.5 animations:^{ 

    label.alpha=0.3; 


}completion:^(BOOL finished) 
{ 
    label.backgroundcolor=[uicolor purplecolor]; 


    [UIView animateWithDuration:0.5 animations:^{ 

     label.alpha=1.0; 

    }completion:^(BOOL finished) 
     { 

     }]; 

}]; 
1

Esta línea de código que funciona para mí. Asegúrese de ajustar las opciones de fundido encadenado Swift:

static func animationButtonTextColor(button : UIButton, toColor : UIColor, duration : NSTimeInterval) { 
    UIView.transitionWithView(button, duration: duration, options: UIViewAnimationOptions.TransitionCrossDissolve, animations: { 
     button.setTitleColor(toColor, forState: .Normal) 
    }, completion: nil) 
    }