You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ScrollView与DragGesture冲突:onEnded未触发且偏移量无法重置

解决ScrollView内拖拽View的手势冲突问题

这个问题我之前做项目时也踩过坑!核心原因是你把DragGesture绑定在了ScrollView上,导致它和ScrollView自带的滚动手势产生了冲突——当你同时进行拖拽和滚动操作时,系统会优先识别ScrollView的滚动手势,直接跳过了你的DragGesture的onEnded回调,所以dragOffset一直保持偏移状态,没法重置。

修复方案:把拖拽手势绑定到目标View上

你需要让DragGesture只作用于那个绿色的Rectangle,而不是整个ScrollView。这样手势的触发目标更明确,就不会和ScrollView的滚动手势抢事件了。修改后的代码如下:

struct ContentView: View {
    @State private var dragOffset: CGSize = .zero
    var body: some View {
        ScrollView {
            Rectangle()
                .frame(width: UIScreen.main.bounds.size.width, height: 300)
                .foregroundColor(.green)
                .offset(x: dragOffset.width)
                // 把手势直接附加到需要拖拽的Rectangle上
                .gesture(
                    DragGesture()
                        .onChanged { value in
                            dragOffset = value.translation
                        }
                        .onEnded { _ in
                            // 用withAnimation包裹,让重置动画更可控
                            withAnimation {
                                dragOffset = .zero
                            }
                        }
                )
        }
    }
}

进阶优化:处理极端冲突场景

如果还是出现拖拽时ScrollView跟着滚动的情况,可以用highPriorityGesture替代gesture,强制让拖拽手势优先被系统识别:

.highPriorityGesture(
    DragGesture()
        .onChanged { value in
            dragOffset = value.translation
        }
        .onEnded { _ in
            withAnimation {
                dragOffset = .zero
            }
        }
)

这样调整后,不管是单独拖拽、单独滚动,还是同时操作,绿色Rectangle都会在拖拽结束后顺利回到初始位置,onEnded回调也能正常执行啦。

内容的提问来源于stack exchange,提问作者Kai Zheng

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.09 16:47:46