refreshable 是 SwiftUI iOS 15+ 提供的 内置下拉刷新 修饰符,用于 ScrollView、List 等可滚动的视图,实现下拉刷新的功能。
它的作用类似于 UIRefreshControl,但更简单,无需手动处理手势,且与 SwiftUI 滚动视图完美兼容。
基本用法
ScrollView {
LazyVStack {
ForEach(activities, id: \.self) { activity in
Text(activity)
.padding()
.frame(maxWidth: .infinity)
.background(Color.gray.opacity(0.1))
.cornerRadius(10)
}
}
}
.refreshable {
await loadNewActivities() // 调用异步刷新方法
}

1、自动检测下拉手势(无需 DragGesture())。
2、支持异步操作,可以 await 加载数据。
3、刷新时会显示系统自带的“加载中”指示器(iOS 原生 UI)。
适用于 List
List 也可以直接使用 .refreshable:
List {
ForEach(items, id: \.self) { item in
Text(item)
}
}
.refreshable {
await loadNewItems()
}

结合 @State 更新数据
struct ContentView: View {
@State private var activities = ["活动 1", "活动 2", "活动 3"]
var body: some View {
ScrollView {
LazyVStack {
ForEach(activities, id: \.self) { activity in
Text(activity)
.padding()
.frame(maxWidth: .infinity)
.background(Color.gray.opacity(0.1))
.cornerRadius(10)
}
}
}
.refreshable {
await refreshActivities()
}
}
func refreshActivities() async {
try? await Task.sleep(nanoseconds: 1_000_000_000) // 模拟网络请求
activities.append("新活动 \(activities.count + 1)") // 添加新数据
}
}

refreshActivities() 需要是 async 方法,支持异步更新数据。
刷新时,系统会自动显示下拉加载动画。
避免阻塞 UI,refreshable 默认运行在后台,刷新完成后自动消失。