如何设置UILabel的textColor属性的动画?


82

由于某些原因,当我尝试为textColor设置动画时,它将无法正常工作。textColor突然从A变为B。是否可以对其进行动画处理,例如从红色变为黑色?

Answers:


6

该答案已过时,对于原始问题不是一个好的解决方案。@strange在下面的答案要好得多,应该代替此答案:https ://stackoverflow.com/a/20892927/76559

//下面的旧答案

textColor属性未在文档中指定为可动画设置,因此我认为您不能使用简单的UIView动画块来实现。

NSTimer每隔几毫秒触发一次,每次将颜色逐渐从另一种设置为另一种时,就可以粗略地做到这一点。

我说这很粗糙,因为它需要从起始颜色到结束颜色的数组或其他一些预设颜色值的容器,而且我敢肯定有一种方法可以使用核心动画或类似方法来完成此操作,我只是不知道不知道那是什么


或:抛出RGB值介于A和B之间且给定百分比的数组的函数。虽然对颜色算法一无所知。
dontWatchMyProfile

这里有很好的解决方法:在这里这里 感谢Anna Karenina
jackal 2012年

4
您应该使用CADisplayLink而不是NSTimer手动驱动动画,因为它与显示更新同步。请参阅WWDC 2014大会236:在13:00左右建立可中断和响应式交互
道格拉斯山

即使当时确实如此,也不应再将其作为接受的答案。看到下面的奇怪的答案
bitwit

Stack Overflow不允许我删除这个过时的答案,因为它已经被接受。在下面查看@strange的答案。
Jasarien

194

相反,您尝试像这样在对象本身上使用交叉淡入淡出过渡,它将为您提供从一种颜色到另一种颜色的不错的淡入淡出效果:

目标C

[UIView transitionWithView:myLabel duration:0.25 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
    myLabel.textColor = NEW_COLOR;
} completion:^(BOOL finished) {
}];

迅速

UIView.transitionWithView(creditsLabel, duration: 0.25, options: .TransitionCrossDissolve, animations: {     
    self.creditsLabel.textColor = UIColor.redColor() 
}, 
completion: nil)

由于各种原因,这比使用NSTimers,CATextLayers等更好。CATextLayer对文本字距调整或NSAttributedText没有适当的支持,并且NSTimers太慢了(加上太多的代码)。上面的过渡动画可以解决问题,也可以在链动画中使用。我遇到了同样的问题,并且已经尝试了上面的解决方案,但是这个简单的代码代替了。


7
尼斯,优雅,实际上是最好,最干净的解决方案。
maksa 2014年

17
大。在Swift中的工作UIView.transitionWithView(creditsLabel, duration: 0.3, options: .TransitionCrossDissolve, animations: { self.creditsLabel.textColor = UIColor.redColor() }, completion: nil)
原理

8
请注意:仅当标签为静态时,此方法才有效。如果执行此操作,并且标签的位置被修改,则淡出动画将显示难看的伪像。
卢卡斯·彼得

在Xcode 10.2.1和Swift 5上对我不起作用。以下“ shokaveli”方法有效
马丁

我一直在寻找一种在SwiftUI中执行此操作的方法,但当时似乎不支持该方法。
philipp

58

Swift 4解决方案:

UIView.transition(with: yourLabel, duration: 0.3, options: .transitionCrossDissolve, animations: {
  self.yourLabel.textColor = .red
}, completion: nil)

请注意,如果你有一个实例这仅适用UILabel于该with财产。如果您执行类似操作transition(with: outerView.label…)并尝试将其设置在内部,则该操作将自动失败。
山姆·索菲斯

由于某种原因对我不起作用。它在动画过程中突然改变而不是逐渐改变。:(
ScottyBlades

1
@ScottyBlades也许您正在后台线程上执行动画?尝试将UIView.transition代码包装在DispatchQueue.main.async {}括号内。
budidino

1
仅供参考-第一次尝试没有用,那是因为我有options: .easeInOut,所以我将其改为.transitionCrossDissolve 工作。
LeoGalante

13

textColor无法设置动画的原因是UILabel使用常规的CALayer而不是CATextLayer。

为了使textColor可以动画(以及文本,字体等),我们可以将UILabel子类化,使其使用CATextLayer。

这是很多工作,但是幸运的是我已经做到了:-)

你可以找到一个完整的解释+这一个简易的开源替代品的UILabel文章


9

您可以尝试创建UILabel的另一个实例或具有textColor的任何实例,然后在这两个实例(具有旧textColor的实例和具有新textColor的实例)之间应用动画。


7

这是唯一对我有用的东西:

let changeColor = CATransition()
changeColor.duration = 1

CATransaction.begin()

CATransaction.setCompletionBlock {
    selected.label.layer.addAnimation(changeColor, forKey: nil)
    selected.label.textColor = .blackColor()
}

selected.nameLabel.textColor = .redColor()

CATransaction.commit()

6

这是我为标签文本颜色设置动画的代码。的重要组成部分,是文字颜色设置为clearColor动画前

label.textColor = [UIColor clearColor];
[UIView transitionWithView:label duration:duration/4 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
    label.textColor = self.highlightedCellPrimaryTextColor;
} completion:^(BOOL finished) { }];

0

我发现将UIView放置在标签下方并对其不透明度设置动画非常容易。标签必须添加到该视图。从资源消耗的角度来看,这可能不是一个好的解决方案,但是非常简单。


0

更新了Swift 3.0

我刚刚从@budidino评论更改

UIView.transition(with: my.label, duration: 0.3, options: .transitionCrossDissolve, animations: { my.label.textColor = .black }, completion: nil)

0

感谢@Strange的回答,它在Swift 5,Xcode 11中完美运行,但语法有所更改。我正在为多个UILabel设置文本颜色的动画,如果这也是您的情况,请尝试以下操作

for label in [label1, label2, ...] as [UILabel] { // loop through a @IBOutlet UILabel array
        UIView.transition(with: label, duration: 0.3, options: .transitionCrossDissolve, animations: {
            label.textColor = .label
        }, completion: nil)
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.