List(items, id: \.self) { item in
Text(item)
}
.refreshable {
await fetchData()
}The .refreshable modifier adds pull-to-refresh support to scrollable views like List. When the user pulls down, the async closure runs and a spinner shows until it finishes.
List { ... }
.refreshable {
await loadData()
}The refresh closure runs only when the user pulls down the list far enough to activate the refresh control.
List(items, id: \.self) { item in
Text(item)
}
.refreshable {
fetchData()
}The .refreshable closure expects an async function to be awaited. If fetchData() is not awaited, SwiftUI never knows when refresh ends, so spinner stays.
The .refreshable modifier was introduced in iOS 15.0, so apps must target at least iOS 15 to use it.
SwiftUI's .refreshable modifier does not expose a way to start refresh programmatically. Using UIKit's UIRefreshControl bridged via UIViewRepresentable is the common workaround.
