如何为 UILabel 的 textColor 属性设置动画?
Posted
技术标签:
【中文标题】如何为 UILabel 的 textColor 属性设置动画?【英文标题】:How to animate the textColor property of an UILabel? 【发布时间】:2011-01-26 11:08:59 【问题描述】:由于某种原因,当我尝试为textColor
设置动画时,它不起作用。 textColor
突然从 A 变为 B。是否可以对其进行动画处理,例如将红色变为黑色?
【问题讨论】:
【参考方案1】:相反,您是否尝试过像这样在对象本身上使用交叉淡入淡出过渡,它会为您提供从一种颜色到另一种颜色的淡入淡出效果:
目标 C
[UIView transitionWithView:myLabel duration:0.25 options:UIViewAnimationOptionTransitionCrossDissolve animations:^
myLabel.textColor = NEW_COLOR;
completion:^(BOOL finished)
];
斯威夫特 5
UIView.transition(with: creditsLabel, duration: 0.25, options: .transitionCrossDissolve)
self.creditsLabel.textColor = .red
由于各种原因,这比使用 NSTimers、CATextLayers 等要好。 CATextLayer 对文本字距调整或 NSAttributedText 没有适当的支持,并且 NSTimers 滞后(加上代码太多)。上面的过渡动画可以解决问题,也可以在链式动画中使用。我遇到了同样的问题,并且已经尝试过上面的解决方案,但是这个简单的代码却可以创造奇迹。
【讨论】:
不错,优雅,实际上是最好和最干净的解决方案。 太棒了。在 Swift 中也一样:UIView.transitionWithView(creditsLabel, duration: 0.3, options: .TransitionCrossDissolve, animations: self.creditsLabel.textColor = UIColor.redColor() , completion: nil)
请注意:这仅在标签为静态时有效。如果您这样做并且标签的位置正在被修改,淡出动画将显示丑陋的工件。
在 Xcode 10.2.1 和 Swift 5 上不适合我。下面的 'shokaveli' 方法可以
我一直在寻找一种在 SwiftUI 中执行此操作的方法,但当时似乎不支持。【参考方案2】:
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 也许你正在后台线程上做动画?尝试将 UIView.transition 代码包装在 DispatchQueue.main.async 括号内。
仅供参考 - 我第一次尝试没有用,那是因为我有 options: .easeInOut
,所以我将其更改为 .transitionCrossDissolve
并工作。【参考方案3】:
textColor 不可动画的原因是 UILabel 使用常规的 CALayer 而不是 CATextLayer。
为了使 textColor 具有动画效果(以及文本、字体等),我们可以继承 UILabel 以使其使用 CATextLayer。
这是一项相当多的工作,但幸运的是我已经做到了:-)
您可以在 article 中找到完整的解释 + UILabel 的嵌入式开源替代品
【讨论】:
【参考方案4】:您可以尝试创建另一个 UILabel 实例或任何具有 textColor 的实例,然后在这两个实例之间应用动画(具有旧 textColor 的实例和具有新 textColor 的实例)。
【讨论】:
【参考方案5】:这是唯一对我有用的东西:
let changeColor = CATransition()
changeColor.duration = 1
CATransaction.begin()
CATransaction.setCompletionBlock
selected.label.layer.add(changeColor, forKey: nil)
selected.label.textColor = .black
selected.nameLabel.textColor = .red
CATransaction.commit()
【讨论】:
【参考方案6】:此答案已过时,不是原始问题的好解决方案。 @strange 下面的答案要好得多,应该代替这个答案:https://***.com/a/20892927/76559
//下面的旧答案
textColor
属性未在文档中指定为可动画,因此我认为您无法使用简单的 UIView 动画块来实现...
这可以通过NSTimer
每隔几毫秒触发一次,每次设置颜色从一个到另一个逐渐设置。
我说这是粗略的,因为它需要一个数组或其他一些预设颜色值的容器,从开始颜色到结束颜色,我相信有一种方法可以使用核心动画或其他东西来做到这一点,我只是不知道它是什么。
【讨论】:
或:一个函数,它抛出一个数组,其 RGB 值介于 A 和 B 之间,并且具有给定的百分比。不过对颜色算法一无所知。 这里有很好的解决方法:here 和 here 感谢 Anna Karenina 您应该使用CADisplayLink
而不是NSTimer
来手动驱动动画,因为它与显示更新同步。 13:00 左右见WWDC 2014 Session 236: Building Interruptible and Responsive Interactions。
这不再是公认的答案,即使当时是真的。见下面奇怪的答案
Stack Overflow 不允许我删除这个过时的答案,因为它已被接受。在下面查看@strange 的答案。【参考方案7】:
这是我为标签文本颜色设置动画的代码。 重要的部分是在动画之前将 textColor 设置为 clearColor
label.textColor = [UIColor clearColor];
[UIView transitionWithView:label duration:duration/4 options:UIViewAnimationOptionTransitionCrossDissolve animations:^
label.textColor = self.highlightedCellPrimaryTextColor;
completion:^(BOOL finished) ];
【讨论】:
【参考方案8】:我发现在标签下方放置一个 UIView 并为其不透明度设置动画非常容易。 必须将标签添加到该视图。 从资源消耗的角度来看,这可能不是一个好的解决方案,但非常简单。
【讨论】:
【参考方案9】:更新了 swift 3.0
我刚从@budidino cmets 改过来
UIView.transition(with: my.label, duration: 0.3, options: .transitionCrossDissolve, animations: my.label.textColor = .black , completion: nil)
【讨论】:
【参考方案10】:感谢@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)
【讨论】:
以上是关于如何为 UILabel 的 textColor 属性设置动画?的主要内容,如果未能解决你的问题,请参考以下文章
如何为多个 UILabel 创建一个 tapGestureRecognizer?