You need to take two colours variables and swap them once animation finished and call the colour changing function recursively.
I answered once here Animate CAGradientLayer in Swift. It looks like same thing.
Although I tried and below is the code which worked for me.
For the convenience I created a custom class of UILabel
which can be use easily.
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)
})
}
}
}
Usage:
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()
}
You can animate label with multiple colours.
