Skip to content

Instantly share code, notes, and snippets.

@DagAgren
Created November 7, 2025 11:33
Show Gist options
  • Select an option

  • Save DagAgren/99671f142c81255c85e8005ab286d5b4 to your computer and use it in GitHub Desktop.

Select an option

Save DagAgren/99671f142c81255c85e8005ab286d5b4 to your computer and use it in GitHub Desktop.
Spring animation with stiffness and damping for the old UIView animation API
extension UIView {
@MainActor class func animate(
springStiffness stiffness: CGFloat,
damping: CGFloat,
initialSpringVelocity: CGFloat = 0.0,
delay: TimeInterval = 0.0,
options: UIView.AnimationOptions = [],
animations: () -> Void,
completion: ((Bool) -> Void)? = nil
) {
let (duration, bounce) = durationAndBounce(forStiffness: stiffness, damping: damping)
animate(
springDuration: duration,
bounce: bounce,
initialSpringVelocity: initialSpringVelocity,
delay: delay,
options: options,
animations: animations,
completion: completion,
)
}
private class func durationAndBounce(forStiffness stiffness: CGFloat, damping: CGFloat) -> (duration: TimeInterval, bounce: CGFloat) {
let duration = 2 * .pi / sqrt(stiffness)
let dampingThreshold = 4 * .pi / duration
let bounce: CGFloat
if damping < dampingThreshold {
bounce = 1 - damping * duration / (4 * .pi)
} else {
bounce = (4 * .pi) / (damping * duration) - 1
}
return (duration: TimeInterval(duration), bounce: bounce)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment