Cómo animar la propiedad textColor de un UILabel?

Por alguna razón, cuando bash animar textColor, no funciona. El textColor simplemente cambia repentinamente de A a B. ¿Es posible animarlo, digamos de rojo a negro?

La propiedad textColour no está especificada como animable en los documentos, por lo que no creo que puedas hacerlo con un simple bloque de animaciones UIView …

Esto probablemente podría hacerse de manera bastante cruda con un NSTimer disparando cada dos milisegundos, cada vez ajustando el color gradualmente de uno a otro.

Digo que es crudo porque requeriría una matriz u otro contenedor de valores de color preestablecidos desde el color inicial hasta el final, y estoy seguro de que hay una manera de hacerlo con la animación central o algo así, simplemente no no se que es

En cambio, si ha intentado usar una transición de fundido cruzado en el objeto en sí, así le dará un efecto de fundido de fade-in agradable de un color a otro:

 [UIView transitionWithView:myLabel duration:0.25 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ myLabel.textColor = NEW_COLOR; } completion:^(BOOL finished) { }]; 

Esto es mejor que usar NSTimers, CATextLayers, etc., por varias razones. CATextLayer no tiene soporte adecuado para el kerning de texto o NSAttributedText, y los NSTimers son laggy (además de que hay demasiado código). La animación de transición de arriba hace el truco, y también se puede usar en una animación en cadena. Tuve el mismo problema y ya he probado las soluciones anteriores, pero este código simple funciona de maravilla.

Solución Swift 4 :

 UIView.transition(with: yourLabel, duration: 0.3, options: .transitionCrossDissolve, animations: { self.yourLabel.textColor = .red }, completion: nil) 

La razón por la que textColor no es animable es que UILabel utiliza un CALayer regular en lugar de un CATextLayer.

Para hacer que el texto pueda ser animado (así como el texto, la fuente, etc.) podemos subclase UILabel para hacer que use un CATextLayer.

Esto es bastante trabajo, pero afortunadamente ya lo hice 🙂

Puede encontrar una explicación completa + un reemplazo de fuente abierta para UILabel en este artículo

Podría intentar crear otra instancia de UILabel o lo que sea que tenga el textColor, y luego aplicar la animación entre esas dos instancias (la del antiguo textColor y la del nuevo textColor).

Aquí está mi código para animar el color del texto de la etiqueta. La parte importante es establecer textColor para clearColor antes de la animación

 label.textColor = [UIColor clearColor]; [UIView transitionWithView:label duration:duration/4 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ label.textColor = self.highlightedCellPrimaryTextColor; } completion:^(BOOL finished) { }]; 

Me resultó bastante fácil colocar una UIView debajo de la etiqueta y animar su opacidad. La etiqueta debe agregarse a esa vista. Tal vez no sea una buena solución desde el punto de vista del consumo de recursos, pero es bastante sencilla.

Esto fue lo ÚNICO que funcionó para mí:

 let changeColor = CATransition() changeColor.duration = 1 CATransaction.begin() CATransaction.setCompletionBlock { selected.label.layer.addAnimation(changeColor, forKey: nil) selected.label.textColor = .blackColor() } selected.nameLabel.textColor = .redColor() CATransaction.commit() 

actualizado rápido 3.0

Acabo de cambiar los comentarios de @budidino

 UIView.transition(with: my.label, duration: 0.3, options: .transitionCrossDissolve, animations: { my.label.textColor = .black }, completion: nil)