如何避免LongPressGesture结束后触发父视图的DragGesture?
解决父视图DragGesture与子视图LongPressGesture冲突问题
要实现长按子视图后移动手指再松开时不触发父视图的DragGesture,核心是通过状态标记让父视图识别当前操作是否来自子视图的长按后续动作,具体修改如下:
修改后的代码
ParentView 部分
struct ParentView: View { @State private var shouldIgnoreDrag = false private let childCount = 3 var body: some View { VStack { ForEach(0..<childCount, id: \.self) { _ in ChildView(shouldIgnoreDrag: $shouldIgnoreDrag) } } .gesture(DragGesture() .onEnded { _ in guard !shouldIgnoreDrag else { shouldIgnoreDrag = false // 重置状态,不执行拖拽 return } // 这里写你的拖拽逻辑 print("父视图拖拽动作执行") }) } }
ChildView 部分
struct ChildView: View { @Binding var shouldIgnoreDrag: Bool @GestureState private var isLongPressing = false var body: some View { HStack { Text("子视图内容") .padding() .background(Color.lightGray.opacity(0.3)) .cornerRadius(6) } .gesture(LongPressGesture(minimumDuration: 1) .updating($isLongPressing) { value, state, _ in state = value if value { // 长按触发时标记需要忽略父视图拖拽 shouldIgnoreDrag = true } } .onEnded { _ in // 长按结束后的自定义操作 print("子视图长按动作执行") // 延迟重置状态,避免松开时误触发父视图拖拽 DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { shouldIgnoreDrag = false } }) } }
核心逻辑说明
- 用
@Binding在父子视图间共享shouldIgnoreDrag状态:子视图触发长按时,将该状态设为true,通知父视图忽略后续的拖拽事件。 - 父视图的DragGesture在触发时先检查状态,若
shouldIgnoreDrag为true则跳过拖拽逻辑并重置状态,否则正常执行。 - 长按结束后延迟重置状态,是为了给系统足够时间处理手势收尾,避免手指松开瞬间的拖拽事件被误触发。
内容的提问来源于stack exchange,提问作者dan_sum
相关产品推荐
相关产品推荐

