Animar el cambio de texto en UILabel
Estoy estableciendo un nuevo valor de texto a UILabel
. Actualmente, el nuevo texto aparece muy bien. Sin embargo, me gustaría añadir alguna animación cuando aparezca el nuevo texto. Me pregunto qué puedo hacer para animar la aparición del nuevo texto.
10 answers
Objetivo-C
Para lograr una transición verdadera de disolución cruzada (la etiqueta antigua se desvanece mientras que la nueva etiqueta se desvanece), no desea desvanecerse a invisible. Daría lugar a parpadeo no deseado incluso si el texto no cambia.
Utilice 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"
Véase también: ¿Animar texto UILabel entre dos números?
Demostración en iOS 10, 9, 8:
Probado con Xcode 8.2.1 & 7.1, ObjectiveC en iOS 10 a 8.0.
► Para descargar el proyecto completo, busque SO-3073520 en Swift Recipes .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:31
Me pregunto si funciona y funciona perfectamente!
Objective-C
[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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-16 10:03:25
Swift 4
La forma correcta de desvanecer un UILabel (o cualquier UIView para el caso) es usar un Core Animation Transition
. Esto no parpadeo, ni fundido a negro si el contenido es invariable.
Una solución portátil y limpia es usar un Extension
en Swift (invocar elementos visibles cambiantes anteriores)
// 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 en Swift Recetas.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-27 17:16:06
Desde iOS4 se puede hacer obviamente con bloques:
[UIView animateWithDuration:1.0
animations:^{
label.alpha = 0.0f;
label.text = newText;
label.alpha = 1.0f;
}];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-28 19:36:14
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];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-06-18 23:28:57
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
})
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-11 09:05:19
Este es un método de extensión C# UIView que se basa en el código de @SwiftArchitect. Cuando el diseño automático está involucrado y los controles necesitan moverse dependiendo del texto de la etiqueta, este código de llamada utiliza la Supervisión de la etiqueta como la vista de transición en lugar de la etiqueta misma. Agregué una expresión lambda para la acción para hacerla más encapsulada.
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";
} );
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-09 04:58:56
Si quieres hacer esto en Swift
con un retraso, prueba 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)
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:59
De acuerdo con sus gustos y necesidades, puede elegir uno de los tres fragmentos de código siguientes para animar los cambios de texto de su UILabel
con alguna animación de disolución cruzada:
1. Usando 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. Usando CATransition
y CATransition
's type
propiedad
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 add(_:forKey:)
key
parámetro
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-21 12:50:30
Swift 4.2 versión de la solución de SwiftArchitect anterior (funciona muy bien):
// Usage: insert view.fadeTransition right before changing content
extension UIView {
func fadeTransition(_ duration:CFTimeInterval) {
let animation = CATransition()
animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
animation.type = CATransitionType.fade
animation.duration = duration
layer.add(animation, forKey: CATransitionType.fade.rawValue)
}
}
Invocación:
// This will fade
aLabel.fadeTransition(0.4)
aLabel.text = "text"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-26 10:50:27