Heres an example in Swift that may help someone
It's an animation on a gradient layer. It's animating the .locations
property.
The critical point as @robMayoff answer explains fully is that:
Surprisingly, when you do a layer animation, you actually set the final value, first, before you start the animation!
The following is a good example because the animation repeats endlessly.
When the animation repeats endlessly, you will see occasionally a "flash" between animations, if you make the classic mistake of "forgetting to set the value before you animate it!"
var previousLocations: [NSNumber] = []
...
func flexTheColors() { // "flex" the color bands randomly
let oldValues = previousTargetLocations
let newValues = randomLocations()
previousTargetLocations = newValues
// IN FACT, ACTUALLY "SET THE VALUES, BEFORE ANIMATING!"
theLayer.locations = newValues
// AND NOW ANIMATE:
CATransaction.begin()
// and by the way, this is how you endlessly animate:
CATransaction.setCompletionBlock{ [weak self] in
if self == nil { return }
self?.animeFlexColorsEndless()
}
let a = CABasicAnimation(keyPath: "locations")
a.isCumulative = false
a.autoreverses = false
a.isRemovedOnCompletion = true
a.repeatCount = 0
a.fromValue = oldValues
a.toValue = newValues
a.duration = (2.0...4.0).random()
theLayer.add(a, forKey: nil)
CATransaction.commit()
}
The following may help clarify something for new programmers. Note that in my code I do this:
// IN FACT, ACTUALLY "SET THE VALUES, BEFORE ANIMATING!"
theLayer.locations = newValues
// AND NOW ANIMATE:
CATransaction.begin()
...set up the animation...
CATransaction.commit()
however in the code example in the other answer, it's like this:
CATransaction.begin()
...set up the animation...
// IN FACT, ACTUALLY "SET THE VALUES, BEFORE ANIMATING!"
theLayer.locations = newValues
CATransaction.commit()
Regarding the position of the line of code where you "set the values, before animating!" ..
It's actually perfectly OK to have that line actually "inside" the begin-commit lines of code. So long as you do it before the .commit()
.
I only mention this as it may confuse new animators.