【问题标题】:How to animate the textColor property of an UILabel?如何为 UILabel 的 textColor 属性设置动画?
【发布时间】:2011-01-26 11:08:59
【问题描述】:

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

【问题讨论】:

    标签: ios swift core-animation


    【解决方案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://stackoverflow.com/a/20892927/76559

          //下面的旧答案

          textColor 属性未在文档中指定为可动画,因此我认为您无法使用简单的 UIView 动画块来实现...

          这可以通过NSTimer 每隔几毫秒触发一次,每次设置颜色从一个到另一个逐渐设置。

          我说这是粗略的,因为它需要一个数组或其他一些预设颜色值的容器,从开始颜色到结束颜色,我相信有一种方法可以使用核心动画或其他东西来做到这一点,我只是不知道它是什么。

          【讨论】:

          • 或:一个函数,它抛出一个数组,其 RGB 值介于 A 和 B 之间,并且具有给定的百分比。不过对颜色算法一无所知。
          • 这里有很好的解决方法:herehere 感谢 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)
                }
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多