Pull to refresh

Also known as: pull-to-refresh

On this page 7

Pull to refresh (also written pull-to-refresh) is a touch gesture for reloading content: when a scrollable list or feed is already at its top, the user drags it further downward past a threshold and releases it, which triggers a request for new data while a progress indicator appears above the content. In mobile UX, it is one of the most widely recognized patterns for user-initiated updates in feeds, inboxes and lists.

The pattern became popular in iPhone apps around the end of the 2000s and was later adopted by both major platforms as a standard system component. Its strength is that it reuses the scroll gesture the user is already making, so no visible refresh button is needed.

How the pull to refresh gesture works

Pull to refresh relies on overscroll at the top edge of a scroll container. While the list is at offset zero, further downward movement is not used for scrolling; instead the content or an indicator follows the finger with increasing resistance, which communicates that something will happen on release.

The interaction passes through clear states. Crossing a trigger distance, commonly a few tens of density-independent pixels or points, arms the refresh. If the user releases before the threshold, the view springs back without loading. After the request completes, the indicator disappears and new items are inserted at the top.

StateUser actionVisual feedback
IdleList rests at the topNo indicator visible
PullingDrag downward below thresholdIndicator appears, grows or rotates with the drag
ArmedDrag beyond the trigger distanceIndicator fully formed, optional haptic tick
RefreshingFinger releasedSpinner animates, content stays offset
CompletedData arrives or request failsIndicator retracts, new items or error message shown
States of a pull to refresh interaction

Platform implementations and parameters

Both mobile platforms provide native components that handle the gesture, physics and accessibility. Using them is usually better than a custom implementation, because they match system behavior that users already expect.

PlatformComponentIndicator style
iOS with UIKitUIRefreshControl attached to a scroll viewSpinner revealed behind the content
iOS with SwiftUIrefreshable modifier on a listSystem spinner with asynchronous task
Android with ViewsSwipeRefreshLayoutCircular indicator sliding over content
Android with Jetpack ComposeMaterial pull to refresh containerMaterial circular indicator
Mobile webBrowser native or custom JavaScriptBrowser-defined or custom
Native pull to refresh components

Key parameters include the trigger distance, the maximum drag distance, the damping curve that creates resistance and the minimum spinner display time, which prevents a distracting flash when data arrives in a few milliseconds. On the web, the CSS property overscroll-behavior lets developers disable the browser’s own pull to refresh when a page implements its own.

Pull to refresh compared with other update patterns

Pull to refresh is only one way to keep content current. Choosing the right pattern depends on how often data changes and whether the user expects to control updates.

PatternWho triggers itBest suited for
Pull to refreshUser, by gestureFeeds, inboxes, lists updated irregularly
Refresh buttonUser, by tapDesktop-like tools, accessibility fallback
Automatic pollingApp, on a timerDashboards with predictable change rates
Push or live updatesServer, in real timeChat, live scores, collaboration
New items bannerServer, user confirmsFeeds where jumping content would disorient
Content update patterns in mobile apps

Many apps combine patterns: content updates in the background or through push, and pull to refresh remains as a reassurance gesture that lets the user confirm that the list is current.

Designing pull to refresh well

Good implementations make the gesture discoverable, forgiving and honest about progress. The indicator should appear as soon as the pull begins, the threshold should be reachable comfortably within the thumb zone, and the result should be visible.

  • Use it only on vertically scrolling lists whose newest content appears at the top.
  • Keep the scroll position stable after refresh, inserting new items without throwing the user away from what they were reading.
  • Show an error state when the request fails, instead of silently retracting the spinner.
  • Offer an alternative action, such as a menu item or button, for users of assistive technology who cannot perform the gesture.
  • Avoid conflicts with other vertical gestures, such as a bottom sheet or a swipe-to-dismiss screen.

Accessibility guidelines expect that every gesture has an accessible equivalent. Screen reader users typically cannot drag a list beyond its top, so a refresh action in the accessibility actions or the toolbar is essential.

Common mistakes with pull to refresh

Most problems come from using the pattern where content does not change or from broken feedback. The table lists frequent issues with their causes and fixes.

SymptomCauseFix
Page reloads unexpectedly on the webBrowser gesture not disabledSet overscroll-behavior on the scroll container
Spinner never stopsCompletion callback not called on errorEnd refreshing in every code path
Spinner flashes brieflyVery fast responseEnforce a short minimum display time
Gesture fires while scrolling up quicklyMomentum crosses the thresholdArm only from a drag that started at the top
Users never discover itOnly refresh method on a static screenAdd automatic updates or a visible control
Pull to refresh problems and fixes

A subtler mistake is treating pull to refresh as a substitute for correct data synchronization. If an app shows stale content until the user pulls, people learn to refresh compulsively and lose trust in the screen. The gesture works best as a confirmation on top of sensible automatic updates, not as the only path to current data.

The idea in brief

Pull to refresh is the move where you drag a list down with your finger and let go to check for anything new. You see a small spinning circle at the top, and a moment later the newest messages or posts appear.

It works because it feels natural: you are already scrolling up to see the latest items, so pulling a little further means show me more. No extra button is needed, which keeps small screens clean.

A practical scenario

A delivery company builds a mobile app for couriers that shows the list of today’s assigned parcels. Assignments change during the day when dispatchers add stops, so the team adds pull to refresh using the native list components on iOS and Android, together with push notifications for urgent changes.

During testing, couriers in areas with weak signal report that the spinner sometimes keeps turning forever. The developers add a 15-second timeout with a clear error message and a retry option, and they also place a refresh action in the toolbar for screen reader users.

After release, couriers rely on the gesture at each stop to confirm their route, and support calls about missing assignments drop, because the list state is always visible and under their control.