How to animate the textColor of a UILabel?

2019-05-28 10:05发布

Could you please tell me how to animate the textColor of a UILabel?

For example I would like to change the color from WHITE to RED, then come back to WHITE with a fade-in effect and repeat that about 3 times.

I need this animation because my app gets real time data from the internet and when a value is changed I need to animate this text value to tell the user that it has changed.

Thank you so much.

7条回答
对你真心纯属浪费
2楼-- · 2019-05-28 10:35

I'm unsure if textColor is animatable on UILabel directly. But if you use a CATextLayer it will be much easier to get this effect,

查看更多
一夜七次
3楼-- · 2019-05-28 10:38

The reason that textColor is not animatable is that UILabel uses a regular CALayer instead of a CATextLayer.

To make textColor animatable (as well as text, font, etc.) we can subclass UILabel and make it use a CATextLayer.

This is quite a lot of work, but luckily I already did it :-)

You can find a complete explanation + a drop-in open source replacement for UILabel in this article

查看更多
beautiful°
4楼-- · 2019-05-28 10:44

This is an old question but currently it's definitely possible to animate the text color with a CrossDissolve. Here's how to do it in Swift:

UIView.transition(with: myLabel, duration: 0.3, options: .transitionCrossDissolve, animations: {
    myLabel.textColor = .white
}, completion: nil)
查看更多
虎瘦雄心在
5楼-- · 2019-05-28 10:49
[UIView transitionWithView:myLabel duration:0.25 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
    label.textColor = [UIColor redColor];
} completion:^(BOOL finished) {
}];

Try :)

查看更多
对你真心纯属浪费
6楼-- · 2019-05-28 10:51

Thanks to this answer - I achieved this with cross dissolve:

extension UILabel {
    func animateTextColor(to color: UIColor) {
        UIView.transition(with: self,
                          duration: 0.25,
                          options: .transitionCrossDissolve,
                          animations: { [weak self] in
                            self?.textColor = color
        })
    }
}

Usage:

label.animateTextColor(to: .red)
查看更多
爷的心禁止访问
7楼-- · 2019-05-28 10:54

The question was asked long ago, but here goes.

As said above, textColor for UILabel is not animate-able. A useful trick is to dynamically create in code another UILabel, with the same attributes and position, but with a destination color. You animate the alpha of the new UILabel from 0.0 to 1.0, so it appears like the textColor of the original UILabel is animated. You can remove one of the labels when the animation is completed.

Here is an example of a class level method that changes to a different textColor for a short while and changes it back.

+(void)colorizeLabelForAWhile:(UILabel *)label withUIColor:(UIColor *)tempColor animated:(BOOL)animated
{
    // We will:
    //      1) Duplicate the given label as a temporary UILabel with a new color.
    //      2) Add the temp label to the super view with alpha 0.0
    //      3) Animate the alpha to 1.0
    //      4) Wait for awhile.
    //      5) Animate back and remove the temporary label when we are done.

    // Duplicate the label and add it to the superview
    UILabel *tempLabel = [[UILabel alloc] init];
    tempLabel.textColor = tempColor;
    tempLabel.font = label.font;
    tempLabel.alpha = 0;
    tempLabel.textAlignment = label.textAlignment;
    tempLabel.text = label.text;
    [label.superview addSubview:tempLabel];
    tempLabel.frame = label.frame;

    // Reveal the temp label and hide the current label.
    if (animated) [UIView beginAnimations:nil context:nil];
    tempLabel.alpha = 1;
    label.alpha = 0;
    if (animated) [UIView commitAnimations];

    // Wait for while and change it back.
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, FOR_AWHILE_TIME*NSEC_PER_SEC), dispatch_get_main_queue(), ^{
        if (animated) {
            // Change it back animated
            [UIView animateWithDuration:0.5 animations:^{
                // Animate it back.
                label.alpha = 1;
                tempLabel.alpha = 0;
            } completion:^(BOOL finished){
                // Remove the tempLabel view when we are done.
                [tempLabel removeFromSuperview];
            }];
        } else {
            // Change it back at once and remove the tempLabel view.
            label.alpha = 1.0;
            [tempLabel removeFromSuperview];
        }
    });
}
查看更多
登录 后发表回答