GeometryReader实现的上拉加载更多
**struct** CustomScrollView<Content: View>: View {
@Binding var refresh: Bool
@ViewBuilder **var** content: Content
@State **var** upOffset: CGFloat = .zero
@State **var** downOffset: CGFloat = .zero
@State **var** contentMax: Bool = **false**
@State **private** **var** topMinY: CGFloat = .zero
@State **private** **var** middleMaxY: CGFloat = .zero
@State **private** **var** bottomMinY: CGFloat = .zero
**var** body: **some** View {
VStack(spacing: 0) {
Color.clear
.frame(height: 0)
.background(
GeometryReader { proxy -> Color **in**
**let** rect = proxy.frame(in: .global)
DispatchQueue.main.async {
topMinY = rect.minY
}
**return** Color.clear
}
)
ScrollView {
content
.background(
GeometryReader { proxy -> Color **in**
**let** rect = proxy.frame(in: .global)
DispatchQueue.main.asyncAfter(deadline: .now()){
middleMaxY = rect.maxY
upOffset = bottomMinY - middleMaxY
downOffset = topMinY-rect.minY
contentMax = bottomMinY - topMinY < rect.height
**if** contentMax {
**if** upOffset > 80 {
refresh = **true**
} **else** {
refresh = **false**
}
} **else** {
**if** downOffset > 80 {
refresh = **true**
} **else** {
refresh = **false**
}
}
}
**return** Color.clear
}
)
}
Color.clear
.frame(height: 0)
.background(
GeometryReader { proxy -> Color **in**
**let** rect = proxy.frame(in: .global)
DispatchQueue.main.async {
bottomMinY = rect.minY
}
**return** Color.clear
}
)
}
}
}
测试代码
**struct** CustomScrollViewTest: View {
@State **var** refresh: Bool = **false**
**var** body: **some** View {
NavigationStack {
VStack {
CustomScrollView(refresh: $refresh) {
LazyVStack(spacing: 15, content: {
ForEach(1 ... 3, id: \.**self**) { index **in**
HStack(spacing: 15, content: {
Circle()
.fill(Color.gray.opacity(0.6))
.frame(width: 70, height: 70)
.overlay {
Text("\(index)")
}
LazyVStack(alignment: .leading, spacing: 15) {
Rectangle()
.fill(Color.gray.opacity(0.6))
.frame(height: 15)
Rectangle()
.fill(Color.gray.opacity(0.6))
.frame(height: 15)
.padding(.trailing, 90)
}
})
.padding()
}
})
.padding(.top)
}
}
.onChange(of: **self**.refresh) { _, newValue **in**
**if** newValue {
print("可加载下一页数据")
}
}
.navigationTitle("refresh=\(refresh.description)")
.navigationBarTitleDisplayMode(.inline)
}
}
}