Swift:UILabel,闪烁文本颜色动画

时间:2019-05-08 10:14:53

标签: ios swift

我想将textColor中的UILabel从Color闪烁为Color,但是我不能这样做。您能帮我吗,这就是我所做的:

extension UILabel {

    func blinkTextColor(fromColor: UIColor, toColor: UIColor, duration: TimeInterval, completion: ((_ view: UIView) -> ())? = nil) {
        UIView.animate(withDuration: duration, delay: 0.0, options: [.curveLinear, .repeat, .autoreverse, .allowUserInteraction], animations: {
            self.textColor = fromColor
            self.textColor = toColor
        }, completion: { _ in
            completion?(self)
        })
    }

}

它不起作用。

2 个答案:

答案 0 :(得分:2)

您需要获取两个颜色变量,并在动画完成后交换它们,然后递归调用颜色更改函数。

我在这里Animate CAGradientLayer in Swift回答了一次。看起来一样。

尽管我尝试过,但以下是对我有用的代码。
为方便起见,我创建了一个易于使用的自定义类UILabel

class BlinkLabel: UILabel, CAAnimationDelegate {

    var colours: [UIColor] = []
    var speed: Double = 1.0
    fileprivate var shouldAnimate = true
    fileprivate var currentColourIndex = 0

    func startBlinking() {
        if colours.count <= 1 {
            /// Can not blink
            return
        }

        shouldAnimate = true
        currentColourIndex = 0
        let toColor = self.colours[self.currentColourIndex]
        animateToColor(toColor)
    }

    func stopBlinking() {
        shouldAnimate = false
        self.layer.removeAllAnimations()
    }

    fileprivate func animateToColor(_ color: UIColor) {

        if !shouldAnimate {return}

        let changeColor = CATransition()
        changeColor.duration = speed
        changeColor.type = .fade
        changeColor.repeatCount = 1
        changeColor.delegate = self
        changeColor.isRemovedOnCompletion = true
        CATransaction.begin()
        CATransaction.setCompletionBlock {
            self.layer.add(changeColor, forKey: nil)
            self.textColor = color
        }
        CATransaction.commit()
    }

    // MARK:- CAAnimationDelegate
    func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
        if flag {

            if !self.shouldAnimate {return}

            /// Calculating the next colour
            self.currentColourIndex += 1
            if self.currentColourIndex == self.colours.count {
                self.currentColourIndex = 0
            }

            let toColor = self.colours[self.currentColourIndex]

            /// You can remove this delay and directly call the function self.animateToColor(toColor) I just gave this to increase the visible time for each colour.
            DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.2, execute: {
                self.animateToColor(toColor)
            })
        }
    }
}

用法:

label.colours = [.red, .green, .blue, .orange]
label.speed = 1.0
label.startBlinking()

/// Stop after 10 seconds
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 10) {
    self.label.stopBlinking()
}

您可以为标签设置多种颜色的动画。

enter image description here

答案 1 :(得分:1)

let changeColor = CATransition()
changeColor.duration = 1
changeColor.type = .fade
changeColor.repeatCount = Float.infinity
CATransaction.begin()
CATransaction.setCompletionBlock {
    self.lbl.layer.add(changeColor, forKey: nil)
    self.lbl.textColor = .green
}
self.lbl.textColor = .red
CATransaction.commit()

enter image description here