Animer un changement de texte dans UILabel

je mets une nouvelle valeur de texte à UILabel . Actuellement, le nouveau texte apparaît très bien. Cependant, j'aimerais ajouter de l'animation lorsque le nouveau texte apparaît. Je me demande ce que je peux faire pour animer l'apparition du nouveau texte.

92
demandé sur IPS Brar 2010-06-19 02:44:03

10 réponses

Objectif-C

pour obtenir une transition vraie Cross-dissolve (ancienne étiquette s'effaçant tandis que nouvelle étiquette s'efface), vous ne voulez pas de fondu à invisible. Il en résulterait scintillement indésirable, même si le texte est inchangé .

utilisez plutôt cette approche:

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"

Voir Aussi: animer UILabel texte entre deux numéros?

démonstration à iOS 10, 9, 8:

Blank, then 1 to 5 fade transition


Testé avec Xcode 8.2.1 & 7.1 , Objectifec sur iOS 10 à 8.0 .

► pour télécharger le projet complet, recherchez SO-3073520 dans Swift Recettes .

147
répondu SwiftArchitect 2017-05-23 11:47:31

je me demande si ça marche et si ça marche parfaitement!

Objectif-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)
141
répondu Anton Gaenko 2018-03-16 10:03:25

Swift 4

la bonne façon de faner un UILabel (ou tout UIView d'ailleurs) est d'utiliser un Core Animation Transition . Cela ne clignotera pas, et ne se fondra pas en noir si le contenu est inchangé.

une solution portable et propre consiste à utiliser un Extension dans Swift (invoquer un changement préalable d'éléments visibles)

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

l'Invocation ressemble à ceci:

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

Blank, then 1 to 5 fade transition


► trouvez cette solution sur Github et des détails supplémentaires sur recettes Swift .

81
répondu SwiftArchitect 2018-05-27 17:16:06

depuis iOS4 il peut évidemment être fait avec des blocs:

[UIView animateWithDuration:1.0
                 animations:^{
                     label.alpha = 0.0f;
                     label.text = newText;
                     label.alpha = 1.0f;
                 }];
21
répondu Mapedd 2012-06-28 19:36:14

voici le code pour que ça marche.

[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];
17
répondu Joo Park 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"
})

ou

UIView.animateWithDuration(0.2, animations: {
    self.sampleLabel.alpha = 1
}, completion: {
    (value: Bool) in
    self.sampleLabel.alpha = 0.2
})
3
répondu A.G 2016-02-11 09:05:19

c'est une méthode d'extension C# UIView basée sur le code de @SwiftArchitect. Lorsque la mise en page automatique est impliquée et que les commandes doivent se déplacer en fonction du texte de l'étiquette, ce code d'appel utilise la Superview de l'étiquette comme vue de transition au lieu de l'étiquette elle-même. J'ai ajouté une expression lambda pour l'action pour la rendre plus encapsulé.

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

code D'appel:

  labelSuperview.FadeTransition( 0.5d, () =>
  {
    if ( condition )
      label.Text = "Value 1";
    else
      label.Text = "Value 2";
  } );
1
répondu Gary Z 2016-08-09 04:58:56

si vous voulez faire ceci dans Swift avec un retard essayez ceci:

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

                    })
                }

        })
    }

utilisant la fonction suivante créée par @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)
}

qui deviendra ceci dans Swift 3

func delay(_ delay:Double, closure:()->()) {
    let when = DispatchTime.now() + delay
    DispatchQueue.main.after(when: when, execute: closure)
}
0
répondu ColossalChris 2017-05-23 11:54:59

selon vos goûts et vos besoins, vous pouvez choisir l'un des trois extraits de code suivants afin d'animer vos modifications de texte UILabel avec un peu d'animation Cross dissolve:

1. Utilisation transition(with:duration:options:animations:completion:)

import UIKit
import PlaygroundSupport

class ViewController: UIViewController {

    let label: UILabel = {
        "151900920".frame.origin = CGPoint(x: 50, y: 50)
        "151900920".text = "Bob"
        "151900920".sizeToFit()
        return "151900920"
    }(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. En utilisant CATransition et CATransition 's type biens

import UIKit
import PlaygroundSupport

class ViewController: UIViewController {

    let label: UILabel = {
        "151910920".frame.origin = CGPoint(x: 50, y: 50)
        "151910920".text = "Bob"
        "151910920".sizeToFit()
        return "151910920"
    }(UILabel())
    let animation: CATransition = {
        "151910920".timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        "151910920".type = kCATransitionFade
        "151910920".duration = 1
        return "151910920"
    }(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. Utiliser CATransition et add(_:forKey:) key paramètre

import UIKit
import PlaygroundSupport

class ViewController: UIViewController {

    let label: UILabel = {
        "151920920".frame.origin = CGPoint(x: 50, y: 50)
        "151920920".text = "Bob"
        "151920920".sizeToFit()
        return "151920920"
    }(UILabel())
    let animation: CATransition = {
        "151920920".timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
        "151920920".duration = 1
        return "151920920"
    }(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
0
répondu Imanou Petit 2017-02-21 12:50:30

Swift 4.2 version de la solution de SwiftArchitect ci-dessus (fonctionne 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)
        }
    }

Invocation:

    // This will fade

aLabel.fadeTransition(0.4)
aLabel.text = "text"
0
répondu winnie-ru 2018-09-26 10:50:27