在SwiftUI中检测DragGesture取消

时间:2019-11-11 19:16:11

标签: ios swift swiftui gesture

所以我有一个带有添加的DragGesture的Rectangle,并且想要跟踪手势的开始,更改和结束。问题是当我在执行手势时将另一根手指放在矩形上时,第一个手势停止调用onChange处理程序,并且不触发onEnded处理程序。 另外,处理程序不会为那只第二只手指开火。

但是如果我在不移开前两根手指的情况下放了第三根手指,则该手势的处理程序将开始触发(依此类推,即使按下也可以取消奇数行)

是错误吗?有没有办法检测到第一个手势已取消?

Rectangle()
  .fill(Color.purple)
  .gesture(
    DragGesture(minimumDistance: 0, coordinateSpace: .local)
      .onChanged() { event in
        self.debugLabelText = "changed \(event)"
      }
      .onEnded() { event in
        self.debugLabelText = "ended \(event)"
      }
  )

1 个答案:

答案 0 :(得分:7)

感谢@krjw用手指的偶数提示

这似乎是Gesture框架中的一个问题,即使我们没有指定它应该监听这些手势,它也试图检测一堆手势。

由于文档非常少,我们只能真正猜测这里的预期行为和生命周期是什么(恕我直言-这似乎是一个错误)-但可以解决。

定义

之类的struct方法
func onDragEnded() {
  // set state, process the last drag position we saw, etc
}

然后将几个手势组合成一个手势,以涵盖我们未指定的基础

let drag = DragGesture(minimumDistance: 0)
      .onChanged({ drag in
       // Do stuff with the drag - maybe record what the value is in case things get lost later on 
      })
      .onEnded({ drag in
        self.onDragEnded()
      })

     let hackyPinch = MagnificationGesture(minimumScaleDelta: 0.0)
      .onChanged({ delta in
        self.onDragEnded()
      })
      .onEnded({ delta in
        self.onDragEnded()
      })

    let hackyRotation = RotationGesture(minimumAngleDelta: Angle(degrees: 0.0))
      .onChanged({ delta in
        self.onDragEnded()
      })
      .onEnded({ delta in
        self.onDragEnded()
      })

    let hackyPress = LongPressGesture(minimumDuration: 0.0, maximumDistance: 0.0)
      .onChanged({ _ in
        self.onDragEnded()
      })
      .onEnded({ delta in
        self.onDragEnded()
      })

    let combinedGesture = drag
      .simultaneously(with: hackyPinch)      
      .simultaneously(with: hackyRotation)
      .exclusively(before: hackyPress)

/// The pinch and rotation may not be needed - in my case I don't but 
///   obviously this might be very dependent on what you want to achieve

对于simultaneouslyexclusively可能会有更好的组合,但是至少对于我的用例(类似于操纵杆),这似乎正在做

还有一种GestureMask类型可能已完成工作,但没有有关其工作方式的文档。