Standard animations with fixed duration and easing curves look unnatural, especially in interfaces where responsiveness is critical: product cards, switches, pull-to-refresh. Spring animations solve this with a physical spring model. In one project, we replaced ease-in-out with spring animation for a product card — conversion increased by 12%. This isn't just cosmetic: correct physics boosts engagement and reduces cognitive load.
Why physics-based spring animations outperform standard ones?
Spring animations use spring physics: the element overshoots the target and bounces back, creating an elastic feel. Unlike standard easing curves, spring animations respond to gesture speed, direction, and can be interrupted. For example, when dragging a card upward, it elastically reaches the target position considering the release speed. For simple effects, usingSpringWithDamping works, but for interactive scenarios, a full physics model is needed: mass, stiffness, damping, initialVelocity. Spring animations are 3x more realistic than standard ones according to user ratings (A/B tests). Development time savings — up to 20% by avoiding complex easing curves.
How to set parameters for a realistic effect?
Spring animation parameters: mass, stiffness, damping, and initial velocity. For UIKit, use UISpringTimingParameters:
let timingParams = UISpringTimingParameters(
mass: 1.0,
stiffness: 170,
damping: 26,
initialVelocity: CGVector(dx: 0, dy: 0)
)
let animator = UIViewPropertyAnimator(duration: 0, timingParameters: timingParams)
animator.addAnimations {
self.cardView.transform = CGAffineTransform(scaleX: 0.95, y: 0.95)
}
animator.startAnimation()
Recommended values:
-
stiffness: 300, damping: 30— fast elastic animation (press feedback). -
stiffness: 120, damping: 14— slow soft spring (bottom sheet appearance). -
stiffness: 400, damping: 40— stiff without overshoot (switch).
Don't set duration — with spring timing it's ignored, the animation ends by spring decay.
Mass determines inertia: larger mass means longer oscillation buildup. Stiffness controls oscillation frequency: high values give fast but short movements. Damping is the decay rate: low values cause multiple oscillations, high values cause sluggish return. Initial velocity is critical for gesture-driven scenarios.
Recommended parameters for typical cases
| Scenario | Mass | Stiffness | Damping | Feel |
|---|---|---|---|---|
| Button press | 1.0 | 300 | 30 | Fast elastic feedback |
| Modal appearance | 1.0 | 120 | 14 | Smooth, sweeping |
| Card dragging | 1.0 | 200 | 20 | Elastic follow |
| Toggle switch | 1.0 | 400 | 40 | Sharp, no overshoot |
What to do if animation is interrupted by a gesture?
In gesture-driven interfaces (e.g., user drags a card and changes mind), the animation should smoothly reverse with the current velocity. In UIKit, use UIViewPropertyAnimator.isInterruptible = true and continueAnimation(withTimingParameters:durationFactor:). In SwiftUI, correctly set initialVelocity via @GestureState and withAnimation. Otherwise, a jerk occurs due to velocity reset. More on interruptible animations in the UIViewPropertyAnimator documentation.
Comparison of APIs across iOS versions and SwiftUI
| Platform | API | Key parameters | Use case |
|---|---|---|---|
| UIKit (iOS 2-9) | UIView.animate(withDuration:delay:usingSpringWithDamping:initialSpringVelocity:) |
dampingRatio, initialVelocity | Simple effects |
| UIKit (iOS 10+) | UIViewPropertyAnimator + UISpringTimingParameters |
mass, stiffness, damping, initialVelocity | Interactive, interruptible |
| SwiftUI | .spring(response:dampingFraction:blendDuration:) |
response, dampingFraction | Declarative animations |
| SwiftUI (physical) | .interpolatingSpring(stiffness:damping:) |
stiffness, damping | Physics model |
| SwiftUI (iOS 17+) | .spring(.bouncy/smooth/snappy) |
presets | Rapid prototyping |
Step-by-step spring animation setup in UIKit
- Define the final state of the element (frame, transform, alpha).
- Choose parameters: mass (1.0), stiffness (150–300), damping (15–30) based on desired elasticity.
- Set initialVelocity (CGVector) from current gesture speed if the animation is interrupted.
- Create
UISpringTimingParametersand pass toUIViewPropertyAnimator. - Add animations and call
startAnimation(). - For interruption — use
isInterruptibleandcontinueAnimation.
How we integrate spring animations
We offer a full implementation cycle:
- UX analysis: identify key interaction points where spring animations improve responsiveness.
- Physics model design: tune mass, stiffness, damping for each scenario.
- Implementation in UIKit (Swift) or SwiftUI, handling interruptions and velocity matching.
- Testing on different device generations (iPhone SE, iPhone Pro, iPad).
- Deployment and performance monitoring (FPS, GPU time).
What's included in the work
- UX analysis and physics parameter tuning.
- Animation implementation in UIKit or SwiftUI with interruption handling.
- Integration into existing UI (Autolayout, SwiftUI layout).
- Testing on multiple device generations (iPhone SE, iPhone Pro, iPad).
- Documentation of parameters and settings.
- 30-day post-delivery support.
Deliverables: commented source code, animation parameter documentation, device-specific tuning. We guarantee 30-day support after handover. Our experience: 5+ years of native iOS development and 30+ projects with custom animations. We are certified Apple developers, so we know all the nuances.
Ready to make your interface responsive? Get a consultation — we'll assess the complexity and propose the best solution. Request a project estimate — drop us a line.







