Anima el cambio de texto en UILabel

Estoy configurando un nuevo valor de texto para un UILabel . Actualmente, el nuevo texto parece estar bien. Sin embargo, me gustaría agregar algo de animación cuando aparece el nuevo texto. Me pregunto qué puedo hacer para animar la apariencia del nuevo texto.

C objective

Para lograr una verdadera transición de disolución cruzada (desvanecimiento de tags antiguas mientras se desvanece la etiqueta nueva), no desea que se desvanezca a invisible. Provocaría un parpadeo no deseado incluso si el texto no se modifica .

Use este enfoque en su lugar:

 CATransition *animation = [CATransition animation]; animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; animation.type = kCATransitionFade; animation.duration = 0.75; [aLabel.layer addAnimation:animation forKey:@"kCATransitionFade"]; // This will fade: aLabel.text = "New" 

Ver también: animar el texto UILabel entre dos números?

Demostración en iOS 10, 9, 8:

En blanco, luego de 1 a 5 transición de fundido


Probado con Xcode 8.2.1 y 7.1 , ObjectiveC en iOS 10 a 8.0 .

► Para descargar el proyecto completo, busque SO-3073520 en Swift Recipes .

Me pregunto si funciona y funciona perfectamente.

C objective

 [UIView transitionWithView:self.label duration:0.25f options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ self.label.text = rand() % 2 ? @"Nice nice!" : @"Well done!"; } completion:nil]; 

Swift 3

 UIView.transition(with: label, duration: 0.25, options: .transitionCrossDissolve, animations: { [weak self] in self?.label.text = (arc4random()() % 2 == 0) ? "One" : "Two" }, completion: nil) 

Swift 4

La forma correcta de desvanecer un UILabel (o cualquier UIView para ese asunto) es usar una Core Animation Transition . Esto no parpadeará, ni se desvanecerá a negro si el contenido no se modifica.

Una solución portátil y limpia es usar una Extension en Swift (invocar elementos visibles que cambian con anterioridad)

 // Usage: insert view.fadeTransition right before changing content extension UIView { func fadeTransition(_ duration:CFTimeInterval) { let animation = CATransition() animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) animation.type = kCATransitionFade animation.duration = duration layer.add(animation, forKey: kCATransitionFade) } } 

La invocación se ve así:

 // This will fade aLabel.fadeTransition(0.4) aLabel.text = "text" 

En blanco, luego de 1 a 5 transición de fundido


► Encuentre esta solución en GitHub y detalles adicionales sobre Recetas Swift .

desde iOS4 obviamente se puede hacer con bloques:

 [UIView animateWithDuration:1.0 animations:^{ label.alpha = 0.0f; label.text = newText; label.alpha = 1.0f; }]; 

Aquí está el código para hacer que esto funcione.

 [UIView beginAnimations:@"animateText" context:nil]; [UIView setAnimationCurve:UIViewAnimationCurveEaseIn]; [UIView setAnimationDuration:1.0f]; [self.lbl setAlpha:0]; [self.lbl setText:@"New Text"; [self.lbl setAlpha:1]; [UIView commitAnimations]; 

Swift 2.0:

 UIView.transitionWithView(self.view, duration: 1.0, options: UIViewAnimationOptions.TransitionCrossDissolve, animations: { self.sampleLabel.text = "Animation Fade1" }, completion: { (finished: Bool) -> () in self.sampleLabel.text = "Animation Fade - 34" }) 

O

 UIView.animateWithDuration(0.2, animations: { self.sampleLabel.alpha = 1 }, completion: { (value: Bool) in self.sampleLabel.alpha = 0.2 }) 

Este es un método de extensión C # UIView que se basa en el código de @ SwiftArchitect. Cuando la distribución automática está involucrada y los controles deben moverse según el texto de la etiqueta, este código de llamada usa la Supervisión de la etiqueta como vista de transición en lugar de la etiqueta misma. Agregué una expresión lambda para la acción para hacerlo más encapsulado.

 public static void FadeTransition( this UIView AView, double ADuration, Action AAction ) { CATransition transition = new CATransition(); transition.Duration = ADuration; transition.TimingFunction = CAMediaTimingFunction.FromName( CAMediaTimingFunction.Linear ); transition.Type = CATransition.TransitionFade; AView.Layer.AddAnimation( transition, transition.Type ); AAction(); } 

Código de llamada:

  labelSuperview.FadeTransition( 0.5d, () => { if ( condition ) label.Text = "Value 1"; else label.Text = "Value 2"; } ); 

Si desea hacer esto en Swift con un retraso, intente esto:

 delay(1.0) { UIView.transitionWithView(self.introLabel, duration: 0.25, options: [.TransitionCrossDissolve], animations: { self.yourLabel.text = "2" }, completion: { finished in self.delay(1.0) { UIView.transitionWithView(self.introLabel, duration: 0.25, options: [.TransitionCrossDissolve], animations: { self.yourLabel.text = "1" }, completion: { finished in }) } }) } 

usando la siguiente función creada por @matt – https://stackoverflow.com/a/24318861/1982051 :

 func delay(delay:Double, closure:()->()) { dispatch_after( dispatch_time( DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)) ), dispatch_get_main_queue(), closure) } 

que se convertirá en esto en Swift 3

 func delay(_ delay:Double, closure:()->()) { let when = DispatchTime.now() + delay DispatchQueue.main.after(when: when, execute: closure) } 

De acuerdo con sus gustos y necesidades, puede elegir uno de los siguientes tres fragmentos de código para animar los cambios de texto de UILabel con alguna animación de disolver cruzada:

1. Uso de transition(with:duration:options:animations:completion:)

 import UIKit import PlaygroundSupport class ViewController: UIViewController { let label: UILabel = { $0.frame.origin = CGPoint(x: 50, y: 50) $0.text = "Bob" $0.sizeToFit() return $0 }(UILabel()) override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white view.addSubview(label) let tapGesture = UITapGestureRecognizer(target: self, action: #selector(toggle(_:))) view.addGestureRecognizer(tapGesture) } func toggle(_ sender: UITapGestureRecognizer) { let animation = { self.label.text = self.label.text == "Bob" ? "Dan" : "Bob" } UIView.transition(with: label, duration: 1, options: .transitionCrossDissolve, animations: animation, completion: nil) } } let controller = ViewController() PlaygroundPage.current.liveView = controller 

2. Uso de la propiedad type CATransition y CATransition

 import UIKit import PlaygroundSupport class ViewController: UIViewController { let label: UILabel = { $0.frame.origin = CGPoint(x: 50, y: 50) $0.text = "Bob" $0.sizeToFit() return $0 }(UILabel()) let animation: CATransition = { $0.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) $0.type = kCATransitionFade $0.duration = 1 return $0 }(CATransition()) override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white view.addSubview(label) let tapGesture = UITapGestureRecognizer(target: self, action: #selector(toggle(_:))) view.addGestureRecognizer(tapGesture) } func toggle(_ sender: UITapGestureRecognizer) { label.layer.add(animation, forKey: nil) label.text = label.text == "Bob" ? "Dan" : "Bob" label.sizeToFit() } } let controller = ViewController() PlaygroundPage.current.liveView = controller 

3. Usando CATransition y el parámetro de key add(_:forKey:)

 import UIKit import PlaygroundSupport class ViewController: UIViewController { let label: UILabel = { $0.frame.origin = CGPoint(x: 50, y: 50) $0.text = "Bob" $0.sizeToFit() return $0 }(UILabel()) let animation: CATransition = { $0.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) $0.duration = 1 return $0 }(CATransition()) override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .white view.addSubview(label) let tapGesture = UITapGestureRecognizer(target: self, action: #selector(toggle(_:))) view.addGestureRecognizer(tapGesture) } func toggle(_ sender: UITapGestureRecognizer) { label.layer.add(animation, forKey: kCATransitionFade) label.text = label.text == "Bob" ? "Dan" : "Bob" label.sizeToFit() } } let controller = ViewController() PlaygroundPage.current.liveView = controller 
Intereting Posts