在SwiftUI中ScrollView本身具有上下滑动的手势,当在ScrollView添加其他监听手势时,可能存在某种冲突。
例如,我想要在《存钱猪猪》的首页,给ScrollView添加refreshable,用于下拉刷新。

但是refreshable调用的异步方法是在下拉后调用的。
我想要实现的场景是,当下拉首页时,如果不松开,首页顶部的进度条会一直旋转,只有松手后再执行其他的代码。
因此,并不适用于调用refreshable中的异步方法。
使用gesture手势
我尝试给ScrollView添加gesture手势,监听手势,当松开时执行其他的代码。
ScrollView(showsIndicators: false) {
}
.refreshable {
// 刷新代码
await refreshPrompt()
}
// 添加拖拽手势监控
.gesture(
DragGesture()
.onChanged { value in
print("进入拖拽状态")
}
.onEnded { _ in
print("松开手势")
}
)
经过我的测试,当我下拉ScrollView时,只会输出onChanged中的“进入拖拽状态”和“进入refreshPrompt方法”。
进入拖拽状态
进入refreshPrompt方法
并不会执行onEnded手势的代码,这也意味着我无法通过onEnded手势判断下拉动作的结束时间,
手势优先级
我尝试其他的方案来解决这一问题,分别使用了highPriorityGesture和simultaneously,但他们都没有解决我的问题。
// 添加拖拽手势监控
.highPriorityGesture(
DragGesture()
.onChanged { value in
print("进入拖拽状态")
}
.onEnded { _ in
print("松开手势")
}
)
仍然不会输出onEnded中的“松开手势。”
进入拖拽状态
进入refreshPrompt方法
总结
最后,还是妥协的将代码放到refreshable中运行,而不是使用gesture手势去监听。
相关文章
1、SwiftUI下拉刷新修饰符refreshable:https://fangjunyu.com/2025/03/20/swiftui%e4%b8%8b%e6%8b%89%e5%88%b7%e6%96%b0%e4%bf%ae%e9%a5%b0%e7%ac%a6refreshable/
2、SwiftUI手势优先级管理:https://fangjunyu.com/2024/12/12/swiftui%e6%89%8b%e5%8a%bf%e4%bc%98%e5%85%88%e7%ba%a7%e7%ae%a1%e7%90%86%e6%96%b9%e6%b3%95/