Estoy estableciendo un nuevo valor de texto a un UILabel. En la actualidad, el nuevo texto parece bien. Sin embargo, me gustaría añadir algunas animación cuando el texto nuevo aparece. Me pregunto qué puedo hacer para animar la aparición del nuevo texto.

  • Para Swift 5, consulte mi respuesta que muestra de 2 maneras diferentes de resolver su problema.
InformationsquelleAutor Joo Park | 2010-06-18

14 Comentarios

  1. 158

    Objective-C

    Para lograr un verdadero disolución cruzada de transición (etiqueta antigua desapareciendo mientras nueva etiqueta fundido), usted no quiere que se desvanecen con el invisible. El resultado sería parpadeo no deseado, incluso si el texto no se modifica.

    El uso de 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"

    Vea también:
    Animar UILabel de texto entre dos números?

    Demostración en iOS, 10, 9, 8:

    Animar el cambio de texto en UILabel


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

    ► Para descargar el proyecto completo, la búsqueda de ASÍ 3073520 en Swift Recetas.

    • Cuando me puse dos etiquetas al mismo tiempo le da a parpadear en el simulador, aunque.
    • Posiblemente mal utilizada? El punto de mi enfoque es no utilizar etiquetas de 2. El uso de una única etiqueta, -addAnimation:forKey a la etiqueta, a continuación, cambie el texto de la etiqueta.
    • por favor, compruebe su estado de cuenta. y comprobar en el proyecto publicado en swiftarchitect.com/recipes/#SO-3073520.
    • Me llegó el mal extremo de la vara sobre esto en el pasado. Pensé que podría definir la transición de una vez por la capa, a continuación, hacer los cambios posteriores y conseguir un ‘libre’ fade. Parece que usted tiene que especificar la transición en cada cambio. Así que – a condición de que usted llame a la transición cada vez, esto funciona muy bien en mi examen en iOS9.
    • Por favor, retire la engañosa pero no parece funcionar en iOS9 si usted siente que ya no es apropiado. Gracias.
    • OMG! Esto es impresionante! Yo no tenía idea de que podría hacer esto! Prueba ahora en mi app 😀
    • ¿Cómo puedo tener el mismo efecto que suceden simultáneamente en más vistas (más etiquetas) una vez que usted haga clic en un botón que cambia de 2-3 etiqueta de texto, por ejemplo? @SwiftArchitect

  2. 157

    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)
    • Tenga en cuenta que el TransitionCrossDissolve es la clave para este trabajo.
    • Usted no necesita [débiles auto] en el UIView la animación de bloques. Consulte stackoverflow.com/a/27019834/511299
  3. 123

    Swift 4

    De la manera adecuada para que aparezca un UILabel (o cualquier UIView, para el caso) es el uso de un Core Animation Transition. Esto no parpadeo, ni fundido a negro si el contenido es invariable.

    Un portátil y limpio solución es utilizar un Extension en Swift (invocar antes de cambiar los elementos visibles)

    //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 se parece a esto:

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

    Animar el cambio de texto en UILabel


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

    • hola he utilizado tu código en mi proyecto, pensé que te interesaría: github.com/goktugyil/CozyLoadingActivity
    • Agradable Si usted podría utilizar la licencia MIT (abogado-hablar de la versión de esa misma licencia), podría ser utilizado en aplicaciones comerciales…
    • Yo no entiendo realmente acerca de la licencia de cosas. Lo que impide a las personas el uso en aplicaciones comerciales ahora?
    • Muchas empresas no pueden utilizar el estándar de licencias a menos que se enumeran en opensource.org/licenses y algunas sólo incorporar Cocoapods la adhesión a opensource.org/licenses/MIT. Que MIT licencia garantiza su Cocoapod puede ser utilizado libremente por todos y de nadie.
    • El problema con el actual PP de la Licencia es que no cubre sus motivos: para empezar, no reclamarlo a usted como el autor (copyright), y como tal, no prueba que puede dar privilegios de distancia. En la Licencia MIT, lo primero que usted reclama derechos de propiedad, que luego podrá utilizar para renunciar a los derechos. Usted realmente debe leer en el MIT si desea profesionales para sacar provecho de su código, y participar a su código abierto esfuerzo.
    • Sí, pero supongo que si «profesional» alguien tenía interés en mi repo, supongo que habría recibido un correo electrónico o un problema. Las pocas personas que están utilizando este se divierten en la licencia y creo que por ahora es el más grande gana de poner una sonrisa en someones cara, que para hacerlo más «profesional».
    • Me ayudó a mí. Quiero saber que cómo ejecutar esto como telón de fondo, porque si tengo una lista de decir el 100 valores y quiero repetir esta lista para un tiempo infinito y simultáneamente puedo acceder o tocar a otro botón en la pantalla. en resumen interfaz de usuario no puede freez

  4. 20

    desde iOS4 puede ser, obviamente, hecho con bloques:

    [UIView animateWithDuration:1.0
                     animations:^{
                         label.alpha = 0.0f;
                         label.text = newText;
                         label.alpha = 1.0f;
                     }];
    • No es un cross-fade transición.
  5. 17

    Aquí está el código para hacer este trabajo.

    [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];
    • Esto no es un desvanecimiento. Este es un fade out, desaparecen por completo, luego se desvanecen. Es básicamente un movimiento lento parpadeo, pero es todavía un parpadeo.
    • por favor, no el nombre de su UILabels lbl
  6. 4

    UILabel Solución De Extensión

    extension UILabel{
    
      func animation(typing value:String,duration: Double){
        let characters = value.map { $0 }
        var index = 0
        Timer.scheduledTimer(withTimeInterval: duration, repeats: true, block: { [weak self] timer in
            if index < value.count {
                let char = characters[index]
                self?.text! += "\(char)"
                index += 1
            } else {
                timer.invalidate()
            }
        })
      }
    
    
      func textWithAnimation(text:String,duration:CFTimeInterval){
        fadeTransition(duration)
        self.text = text
      }
    
      //followed from @Chris and @winnie-ru
      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)
      }
    
    }

    Simplemente se Llama función de

    uiLabel.textWithAnimation(text: "text you want to replace", duration: 0.2)

    Gracias por todos los consejos de los chicos. Espero que esto le ayudará en el largo plazo

  7. 3

    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
    })
    • El primero funciona, pero el segundo solo llamadas finalización de inmediato, independientemente de la duración que me pasa. Otro problema es que no puede presionar cualquier botón mientras estoy con la animación de la primera solución.
    • Para permitir interacciones durante la animación, he añadido una opción, las opciones de: [.TransitionCrossDissolve, .AllowUserInteraction]
    • En la primera opción de usar el auto.vista hace que todo el cambio de vista, esto significa que sólo TransitionCrossDissolve puede ser utilizado. En lugar de eso es mejor para la transición sólo el texto: «UIView.transitionWithView(auto.sampleLabel, duración: 1.0…». También en mi caso funcionó mejor con «…, de finalización: nil)».
  8. 2

    Swift versión 4.2 de SwiftArchitect de la solución anterior (grandes obras):

        //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"
  9. 2

    Swift 4.2 solución (tomando 4.0 respuesta y actualización para los nuevos enumeraciones para compilar)

    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)
        }
    }
    
    func updateLabel() {
    myLabel.fadeTransition(0.4)
    myLabel.text = "Hello World"
    }
  10. 1

    Este es un C# UIView método de extensión que se basa en @SwiftArchitect del código. Cuando el auto de diseño está involucrado y de los controles necesitan para mover según el texto de la etiqueta, este código de llamada se utiliza el Superview de la etiqueta, ya que la transición de vista en lugar de la etiqueta en sí. He añadido una expresión lambda para la acción para hacer 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";
      } );
  11. 1

    El sistema de valores predeterminados de 0.25 para duration y .curveEaseInEaseOut para timingFunction son a menudo preferible para la consistencia a través de animaciones, y puede ser omitida:

    let animation = CATransition()
    label.layer.add(animation, forKey: nil)
    label.text = "New text"

    que es lo mismo que escribir esto:

    let animation = CATransition()
    animation.duration = 0.25
    animation.timingFunction = .curveEaseInEaseOut
    label.layer.add(animation, forKey: nil)
    label.text = "New text"
  12. 1

    Con Swift 5, usted puede elegir uno de los dos siguientes Patio ejemplos de código con el fin de animar a su UILabel‘s cambios de texto con algunos disolución cruzada de animación.


    #1. El uso de UIView‘s transición(con:duración:opciones:animaciones:finalización:) método de clase

    import UIKit
    import PlaygroundSupport
    
    class ViewController: UIViewController {
    
        let label = UILabel()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            label.text = "Car"
    
            view.backgroundColor = .white
            view.addSubview(label)
    
            label.translatesAutoresizingMaskIntoConstraints = false
            label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
            label.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    
            let tapGesture = UITapGestureRecognizer(target: self, action: #selector(toggle(_:)))
            view.addGestureRecognizer(tapGesture)
        }
    
        @objc func toggle(_ sender: UITapGestureRecognizer) {
            let animation = {
                self.label.text = self.label.text == "Car" ? "Plane" : "Car"
            }
            UIView.transition(with: label, duration: 2, options: .transitionCrossDissolve, animations: animation, completion: nil)
        }
    
    }
    
    let controller = ViewController()
    PlaygroundPage.current.liveView = controller

    #2. El uso de CATransition y CALayer‘s add(_:forKey:) método

    import UIKit
    import PlaygroundSupport
    
    class ViewController: UIViewController {
    
        let label = UILabel()
        let animation = CATransition()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            label.text = "Car"
    
            animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
            //animation.type = CATransitionType.fade //default is fade
            animation.duration = 2
    
            view.backgroundColor = .white
            view.addSubview(label)
    
            label.translatesAutoresizingMaskIntoConstraints = false
            label.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
            label.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    
            let tapGesture = UITapGestureRecognizer(target: self, action: #selector(toggle(_:)))
            view.addGestureRecognizer(tapGesture)
        }
    
        @objc func toggle(_ sender: UITapGestureRecognizer) {
            label.layer.add(animation, forKey: nil) //The special key kCATransition is automatically used for transition animations
            label.text = label.text == "Car" ? "Plane" : "Car"
        }
    
    }
    
    let controller = ViewController()
    PlaygroundPage.current.liveView = controller
  13. 0

    Si quieres 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, creado por @mate – 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á esto en Swift 3

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

    Hay una solución para lograr esto. Fue descrito aquí. La idea es crear subclases de UILabel y primordial action(for:forKey:) función de la siguiente manera:

    class LabelWithAnimatedText: UILabel {
        override var text: String? {
            didSet {
                self.layer.setValue(self.text, forKey: "text")
            }
        }
    
        override func action(for layer: CALayer, forKey event: String) -> CAAction? {
            if event == "text" {
                if let action = self.action(for: layer, forKey: "backgroundColor") as? CAAnimation {
                    let transition = CATransition()
                    transition.type = kCATransitionFade
    
                    //CAMediatiming attributes
                    transition.beginTime = action.beginTime
                    transition.duration = action.duration
                    transition.speed = action.speed
                    transition.timeOffset = action.timeOffset
                    transition.repeatCount = action.repeatCount
                    transition.repeatDuration = action.repeatDuration
                    transition.autoreverses = action.autoreverses
                    transition.fillMode = action.fillMode
    
                    //CAAnimation attributes
                    transition.timingFunction = action.timingFunction
                    transition.delegate = action.delegate
    
                    return transition
                }
            }
            return super.action(for: layer, forKey: event)
        }
    }

    Ejemplos de uso:

    //do not forget to set the "Custom Class" IB-property to "LabelWithAnimatedText"
    //@IBOutlet weak var myLabel: LabelWithAnimatedText!
    //...
    
    UIView.animate(withDuration: 0.5) {
        myLabel.text = "I am animated!"
    }
    myLabel.text = "I am not animated!"

Dejar respuesta

Please enter your comment!
Please enter your name here