Last active
December 22, 2020 20:47
-
-
Save matt-curtis/9a9d2ca80a9637f49ba59d702bc7ab96 to your computer and use it in GitHub Desktop.
CALayer.shadowPath and CALayer.path don't overshoot when spring animated.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import PlaygroundSupport | |
class View: UIView { | |
override init(frame: CGRect) { | |
super.init(frame: frame) | |
layer.shadowOpacity = 1 | |
layer.shadowColor = UIColor.black.cgColor | |
layer.shadowOffset = .zero | |
layer.shadowRadius = 5 | |
let startPath = UIBezierPath( | |
roundedRect: CGRect( | |
x: 75, y: 75, | |
width: 250, height: 250 | |
), | |
byRoundingCorners: .allCorners, | |
cornerRadii: CGSize(width: 50, height: 50) | |
).cgPath | |
layer.shadowPath = startPath | |
let endPath = UIBezierPath( | |
roundedRect: CGRect( | |
x: 150, y: 150, | |
width: 100, height: 100 | |
), | |
byRoundingCorners: .allCorners, | |
cornerRadii: CGSize(width: 25, height: 25) | |
).cgPath | |
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(2)) { | |
let springAnimation = CASpringAnimation(keyPath: "shadowPath") | |
springAnimation.duration = springAnimation.settlingDuration | |
springAnimation.damping = 1 | |
springAnimation.fromValue = startPath | |
springAnimation.toValue = endPath | |
self.layer.add(springAnimation, forKey: nil) | |
CATransaction.begin() | |
CATransaction.disableActions() | |
self.layer.shadowPath = endPath | |
CATransaction.commit() | |
} | |
} | |
required init?(coder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
} | |
let backgroundView = UIView(frame: CGRect(x: 0, y: 0, width: 400, height: 400)) | |
backgroundView.backgroundColor = .white | |
let shadowOnlyView = View(frame: CGRect(x: 0, y: 0, width: 400, height: 400)) | |
backgroundView.addSubview(shadowOnlyView) | |
PlaygroundPage.current.liveView = backgroundView |
(This is a deviation from the main issue, but there's also an issue where CABasicAnimation.byValue
and CABasicAnimation.isAdditive
are ignored when animating CGPath
properties. When UIViewPropertyAnimator
generates animations, they're additive by default, so this gap prevents proper support for UIViewPropertyAnimator
-based animations of path properties. This issue is not demonstrated here, though — none of the code below makes uses of additive animations.)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment