Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Animate text change in UILabel

I wonder if it works, and it works perfectly!

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, 4, 5

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

Objective-C

To achieve a true cross-dissolve transition (old label fading out while new label fading in), you don't want fade to invisible. It would result in unwanted flicker even if text is unchanged.

Use this approach instead:

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"

Also see: Animate UILabel text between two numbers?

Demonstration in iOS 10, 9, 8:

Blank, then 1 to 5 fade transition


Tested with Xcode 8.2.1 & 7.1, ObjectiveC on iOS 10 to 8.0.

► To download the full project, search for SO-3073520 in Swift Recipes.


Swift 4

The proper way to fade a UILabel (or any UIView for that matter) is to use a Core Animation Transition. This will not flicker, nor will it fade to black if the content is unchanged.

A portable and clean solution is to use a Extension in Swift (invoke prior changing visible elements)

// 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 looks like this:

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

Blank, then 1 to 5 fade transition


► Find this solution on GitHub and additional details on Swift Recipes.


since iOS4 it can be obviously done with blocks:

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