The problem is that when the layer is deleted, it stops the animation. But when the animation stops, animationDidStop still raises a call that starts a new animation. So, you delete the layer that stops the animation, immediately starts another, but you start another animation. You have duel animations.
You can check the flag to make sure the animation is finished correctly before animationDidStop should call animateLayer .
override func animationDidStop(anim: CAAnimation, finished flag: Bool) { if flag { toColors = fromColors; fromColors = gradient!.colors! animateLayer() } }
Personally, I'm not sure why you delete and add and remove this layer. And if you were, I'm not sure why you are not just gradient?.removeFromSuperlayer() , and not iterating through layers.
Regardless of the fact that I just left the gradient layer, just check its presentationLayer and start the animation from there:
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() fromColors = [dayTopColor.CGColor, dayBottomColor.CGColor] toColors = [dayToTopColor.CGColor, dayToBottomColor.CGColor] gradient = CAGradientLayer() gradient!.colors = fromColors! gradient!.frame = view.bounds view.layer.addSublayer(gradient!) animateLayer() } let dayTopColor = CommonUtils.colorWithHexString("955EAC") let dayBottomColor = CommonUtils.colorWithHexString("9F3050") let dayToTopColor = CommonUtils.colorWithHexString("D15B52") let dayToBottomColor = CommonUtils.colorWithHexString("CC4645") let nightTopColor = CommonUtils.colorWithHexString("2D5E7C") let nightBottomColor = CommonUtils.colorWithHexString("19337D") let nightToTopColor = CommonUtils.colorWithHexString("21334E") let nightToBottomColor = CommonUtils.colorWithHexString("101A55") var gradient : CAGradientLayer? var toColors : [CGColor]? var fromColors : [CGColor]? var day = true func toggleFromDayToNight() { day = !day if day { fromColors = [dayTopColor.CGColor, dayBottomColor.CGColor] toColors = [dayToTopColor.CGColor, dayToBottomColor.CGColor] } else { fromColors = [nightTopColor.CGColor, nightBottomColor.CGColor] toColors = [nightToTopColor.CGColor, nightToBottomColor.CGColor] } let colors = (gradient!.presentationLayer() as! CAGradientLayer).colors
source share