ios objective-c ipad uilabel caanimation

ios - Anima el cambio de texto en UILabel



objective-c ipad (9)

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 objetivo

Para lograr una verdadera transición de disolución cruzada (desvanecimiento de etiquetas 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:

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 .


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"

► Encuentre esta solución en GitHub y detalles adicionales sobre SO-3073520 .


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];


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


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"; } );


Me pregunto si funciona y funciona perfectamente.

C objetivo

[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)


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://.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) }


desde iOS4 obviamente se puede hacer con bloques:

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


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 })