iOS Pull-to-Refresh With a Custom Lottie Animation
Customize the spinner, not the gesture: people already know how to pull to refresh, so make it delightful, not unfamiliar.
TL;DR
A custom pull-to-refresh animation can replace the default spinner with something on-brand, like a Lottie, without breaking the gesture users already know. Build it from a free VP0 design, keep the standard pull-down behavior and SwiftUI refreshable semantics, show clear pulling, loading, and done states, and make sure it never blocks or delays the content. Delight the motion, but keep the mechanics native.
The default pull-to-refresh spinner is fine, but a custom animation can make the moment feel on-brand. The short answer: build a custom pull-to-refresh from a free VP0 design with a Lottie or custom view, keep the native pull-down gesture and refresh semantics intact, show clear pulling, loading, and done states, and never let the animation block the content. Speed perception matters: Google found 53% of mobile visits are abandoned if loading takes too long, so refresh should feel fast, not theatrical.
Customize the motion, keep the gesture
Pull-to-refresh works because it is universal: pull down past the top, release, see new content. That muscle memory is valuable, so customize the look, not the mechanics. The animation should have three readable phases: pulling (responding to the drag, often with progress tied to pull distance), loading (the active refresh), and done (a quick settle back to content). Keep it short, this is a loading indicator, not a show, and make sure releasing actually triggers the refresh on time. Apple’s Human Interface Guidelines treat refresh as a standard pattern to enhance, not reinvent. The familiarity is an asset, so spend your creativity on the visual, not the mechanics.
Build it from a free design
VP0 is a free iOS design library for AI builders. Pick a list or feed design, copy its link, and have Cursor or Claude Code rebuild it in SwiftUI using the native refreshable modifier, then swap the indicator for your custom animation while keeping that standard behavior. Tie the animation’s progress to the pull distance so it feels responsive, and trigger the actual data load on release. Keep the Lottie file small so it stays smooth, and ensure the list is usable the instant the refresh completes, never trap content behind a lingering animation. A light haptic on trigger adds polish, see haptic feedback UI design guidelines iOS. For overall finish, see how to make my app look better.
Pull-to-refresh states
Design all three phases clearly.
| Phase | What the user sees | Note |
|---|---|---|
| Pulling | Animation responds to drag | Progress tied to distance |
| Triggered | A light haptic on release | Confirms the action |
| Loading | The active refresh animation | Short, on-brand |
| Done | Quick settle to content | Never linger |
| Content | List usable immediately | No blocking |
Common mistakes
The first mistake is breaking the gesture, a custom view that no longer triggers on a normal pull. The second is a long, theatrical animation that delays the content people came for. The third is a heavy Lottie file that stutters during the pull. The fourth is no clear loading or done state, leaving users unsure if it worked. The fifth is blocking the list until the animation finishes. Delight is welcome; friction is not.
A worked example
Say you have a feed app. You build the list from a VP0 design with SwiftUI’s refreshable, then replace the spinner with a small branded Lottie. As the user pulls, the animation fills in proportion to the drag; on release a light haptic fires and the loading loop plays while data fetches; when it finishes, it settles in a beat and the fresh content is immediately usable. The file is tiny, so even an older phone stays smooth. For a scroll-driven header effect that pairs with it, see parallax scroll header UI mobile, and to wrap the first run in motion, see Lottie animations for onboarding screens free.
Key takeaways
- A custom pull-to-refresh can be on-brand without breaking the familiar gesture.
- Build it from a free VP0 design on SwiftUI’s refreshable, then swap the indicator.
- Design clear pulling, loading, and done phases and tie progress to pull distance.
- Keep the animation short and the Lottie small; refresh should feel fast.
- Never block or delay the content behind a lingering animation.
Frequently asked questions
How do I add a custom pull-to-refresh animation on iOS? Build the list from a free VP0 design with SwiftUI’s refreshable modifier, then replace the default spinner with a small custom or Lottie animation while keeping the standard pull-down behavior.
Will a custom animation break the refresh gesture? It should not, if you build on the native refreshable behavior and only swap the visual indicator. Avoid fully custom gesture handling that loses the expected pull-to-refresh action.
Should the refresh animation be long and flashy? No. It is a loading indicator, not a show. Keep it short and on-brand, tie it to the pull distance, and make sure the content is usable the moment the refresh completes.
Are Lottie pull-to-refresh animations slow? Only if the file is large. Keep the JSON small and simple, and test on older devices, so the animation stays smooth during the pull and the refresh feels fast.
Frequently asked questions
How do I add a custom pull-to-refresh animation on iOS?
Build the list from a free VP0 design with SwiftUI's refreshable modifier, then replace the default spinner with a small custom or Lottie animation while keeping the standard pull-down behavior.
Will a custom animation break the refresh gesture?
It should not, if you build on the native refreshable behavior and only swap the visual indicator. Avoid fully custom gesture handling that loses the expected pull-to-refresh action.
Should the refresh animation be long and flashy?
No. It is a loading indicator, not a show. Keep it short and on-brand, tie it to the pull distance, and make sure the content is usable the moment the refresh completes.
Are Lottie pull-to-refresh animations slow?
Only if the file is large. Keep the JSON small and simple, and test on older devices, so the animation stays smooth during the pull and the refresh feels fast.
Part of the Native Apple & SwiftUI: The iOS Ecosystem hub. Browse all VP0 topics →
Keep reading
Lottie Animations for Onboarding Screens, Free Start
Lottie brings lightweight motion to onboarding. Build animated welcome screens from a free VP0 design, use Lottie wisely, and never let motion block the value.
Progress Ring Animation in SwiftUI: Rings That Motivate
Apple Watch-style activity rings make progress feel rewarding. Build a smooth animated progress ring from a free VP0 design in SwiftUI, accessible and honest.
Parallax Scroll Header UI: Smooth Depth on Mobile
A parallax header adds depth as the user scrolls. Build a smooth scroll-linked header from a free VP0 design, keep it 60fps, and never sacrifice readability.
Pulsing Radar Animation for Maps: Alive, Not Annoying
A pulsing radar animation signals live location and nearby search. Build a smooth radar pulse from a free VP0 design, keep it subtle, and respect the battery.
Spotify-Style Music Player UI in SwiftUI, Done Right
Want a Spotify-style player? Build the library, now-playing, and mini-player from a free VP0 design in SwiftUI, learn the pattern, and bring your own brand.
Apple HIG UI Kit: How to Get One Free (and Use It)
You don't need to buy an Apple HIG UI kit. Start from a free native-looking VP0 design, turn it into components, and pair it with Apple's free HIG and SF Symbols.