import SwiftUI
struct iOS16RefreshFixView: View {
@State private var dataList: [String] = Array(1...20).map { "初始数据 - \($0)" }
@State private var isLoadingMore = false
@State private var hasMoreData = true
// 用于手动控制刷新状态(iOS 16 兼容)
@State private var isRefreshing = false
var body: some View {
// iOS 16 中使用 ScrollView + LazyVStack 替代 List,避免刷新兼容性问题
ScrollView {
LazyVStack(spacing: 16, pinnedViews: [.sectionHeaders]) {
// 刷新指示器(iOS 16 手动实现)
if isRefreshing {
ProgressView()
.padding(.vertical, 12)
.id("refreshIndicator")
}
// 数据列表
ForEach(dataList, id: \.self) { data in
Text(data)
.padding(.vertical, 12)
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal)
.background(Color(.systemBackground))
.cornerRadius(8)
.shadow(color: .black.opacity(0.05), radius: 1, x: 0, y: 1)
}
// 加载更多指示器
if hasMoreData {
ProgressView("加载中...")
.padding(.vertical, 20)
.onAppear {
loadMoreIfNeeded()
}
} else {
Text("没有更多数据了")
.foregroundColor(.gray)
.padding(.vertical, 20)
.frame(maxWidth: .infinity)
}
}
.padding(.vertical)
}
// iOS 16 兼容的下拉刷新实现
.simultaneousGesture(
DragGesture(minimumDistance: 30)
.onEnded { gesture in
// 检测下拉方向和距离,触发刷新
if gesture.translation.height > 50, !isRefreshing, !isLoadingMore {
isRefreshing = true
Task {
await refreshData()
isRefreshing = false
}
}
}
)
// 为 iOS 15+ 保留系统原生刷新(可选)
.refreshable {
await refreshData()
}
.navigationTitle("iOS 16 兼容刷新")
.onAppear {
// 适配 iOS 16 滚动行为
if #available(iOS 16, *) {
UIScrollView.appearance().bounces = true
}
}
}
private func loadMoreIfNeeded() {
guard !isLoadingMore && hasMoreData else { return }
Task { await loadMoreData() }
}
private func refreshData() async {
// 模拟网络请求
try? await Task.sleep(nanoseconds: 1_500_000_000)
await MainActor.run {
dataList = Array(1...20).map { "刷新后数据 - \($0)" }
hasMoreData = true
}
}
private func loadMoreData() async {
isLoadingMore = true
defer { isLoadingMore = false }
try? await Task.sleep(nanoseconds: 1_500_000_000)
let newData = Array(dataList.count+1 ... dataList.count+10).map { "加载更多数据 - \($0)" }
await MainActor.run {
dataList.append(contentsOf: newData)
if dataList.count >= 50 {
hasMoreData = false
}
}
}
}
#Preview {
NavigationStack {
iOS16RefreshFixView()
}
}