如何为SwiftUI中的ScrollView添加下拉刷新功能?
解决方案
你误解了refreshable的适用范围——从iOS 15开始,refreshable修饰符可以直接应用在ScrollView上,并非仅支持List。下面是修改后的代码,实现下拉刷新功能:
步骤1:提取数据加载逻辑(避免重复代码)
先把onAppear里的数据获取逻辑抽成独立方法,让页面初次加载和下拉刷新可以复用同一逻辑:
struct MarketplaceProductView: View { @StateObject var marketplaceModel = MarketplaceViewModel() // 遵循Swift命名规范,变量名首字母小写 @Namespace var animation @State var showDetailProduct = false @State var selectedProduct: Product? // 用可选类型替代隐式解包,避免空值崩溃风险 // 统一的数据加载方法 private func loadProducts() { guard let stringOne = UserDefaults.standard.string(forKey: "key") else { // 可在这里处理key不存在的异常情况,比如提示用户登录 return } marketplaceModel.fetchProductData(key: stringOne) } var body: some View { ZStack{ VStack { HStack{ Image(systemName: "magnifyingglass") TextField("Search", text: $marketplaceModel.search) } if marketplaceModel.products.isEmpty { ProgressView() } else { // 给ScrollView添加下拉刷新功能 ScrollView(.vertical, showsIndicators: false) { LazyVGrid(columns: Array(repeating: GridItem(.flexible(), spacing: 10), count: 2), spacing: 20) { ForEach(marketplaceModel.filteredProduct) { product in ProductView(productData: product) .onTapGesture { withAnimation { selectedProduct = product showDetailProduct.toggle() } } } } } // 核心:添加下拉刷新修饰符 .refreshable { loadProducts() } } } if showDetailProduct, let selectedProduct = selectedProduct { ProductDetailView2(showDetailProduct: $showDetailProduct, productData: selectedProduct, product_id: selectedProduct.id) // 这里建议替换为实际产品ID字段,比如selectedProduct.id } } .onAppear(perform: loadProducts) } }
关键修改点:
- 直接给
ScrollView附加.refreshable修饰符,闭包内调用统一的数据加载方法 - 提取
loadProducts方法,避免onAppear和刷新逻辑重复 - 优化变量命名和可选类型使用,提升代码安全性和可读性
注意事项:
- 确保项目部署目标为iOS 15.0+,官方
refreshable对ScrollView的支持从iOS15开始 - 如果需要兼容iOS14及以下版本,可以考虑使用第三方下拉刷新库,但官方方案是最优选择
内容的提问来源于stack exchange,提问作者Mxyb
相关产品推荐
相关产品推荐

