For a CALayer custom property defined as below, the UIView.animateKeyframes() and a key defined with UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 1) does NOT last the same duration as the UIView.animate.
UI.animate is correct (10s in my test) but UIView.animateKeyframes is really faster (around 1s to do the job).
Any ideas?
class AnimatedLayer: CALayer {
@NSManaged var progress: CGFloat
// Whenever a new presentation layer is created, this function is called and makes a COPY of the object.
override init(layer: Any) {
super.init(layer: layer)
if let layer = layer as? AnimatedLayer {
progress = layer.progress
}
}
override init() {
super.init()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override class func needsDisplay(forKey key: String) -> Bool {
if isAnimationKeySupported(key) {
return true
}
return super.needsDisplay(forKey: key)
}
override func action(forKey event: String) -> CAAction? {
if AnimatedLayer.isAnimationKeySupported(event) {
let animation = currentAnimationContext(in: self) ?? CABasicAnimation(keyPath: event)
animation.keyPath = event
if let presentation = presentation() {
animation.fromValue = presentation.value(forKeyPath: event)
}
animation.toValue = nil
return animation
}
return super.action(forKey: event)
}
private class func isAnimationKeySupported(_ key: String) -> Bool {
return key == #keyPath(progress)
}
private func currentAnimationContext(in layer: CALayer) -> CABasicAnimation? {
let animation = action(forKey: #keyPath(backgroundColor)) as? CABasicAnimation
return animation?.copy() as? CABasicAnimation
}
}