如何为 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)

【讨论】:

注意,这仅适用于 UILabelwith 属性实例。如果您执行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 设置黑色透明? [复制]

如何为多个 UILabel 创建一个 tapGestureRecognizer?

如何为 UILabel 的文本添加渐变,而不是背景?

iOS UILabel.appearance().textColor 不可用

如何为 UILabel 字体更改设置动画?

如何为 UILabel 设置“粗体”动态字体类型?