For more dynamic speed change, I has some issue with the previous answer (layer not drawing at all) since the timeOffset
needed to be calculated with the new speed in mind.
(source https://coveller.com/2016/05/core_animation_timing)
The base formula for the timeOffset
is:
timeOffset = CACurrentMediaTime() - ((convertTime - beginTime) x speed)
In code:
theLayer.speed = newSpeed
let mediaTime = CACurrentMediaTime()
let converedTime = theLayer.convertTime(mediaTime, to: nil)
theLayer.beginTime = mediaTime
let offset = mediaTime - ((converedTime - theLayer.beginTime) * Double(newSpeed))
theLayer.timeOffset = offset