用于iOS / macOS开发的拖动手势识别器(具有初始位置)

众所周知,在计算机上使用鼠标时,按下鼠标按钮会发生拖动操作,然后移动设备,最后释放按钮。 这是连续且精确的操作。

iOS中,我们使用了(不太精确的)触摸,但是有时我们确实希望在开始,移动以及最终结束触摸时对拖动操作做出类似的反应。

UIPanGestureRecognizer本身可以很好地识别此类拖动操作,只是当其达到开始状态时,用户已经稍微移动了触摸,并且我们不再知道初始位置-没有locationInViewWhenTouchesBegan属性-而我们需要它来准确计算坐标增量以响应拖动操作。

(以一种预期的方式,因为我们不希望在第一次触摸开始时立即开始平移操作,因为我们正在等待用户是否真正想平移或执行其他操作。)

更新:虽然这很烦人,但它也是NSPanGestureRecognizermacOS Cocoa开发中与鼠标事件一起工作的方式,只是很难看到那里的行为。 要解决该问题,您需要开始用鼠标从元素可拖动区域的限制向该元素外部的空间拖动。

为了解决这个问题(至少在今天),我们需要自己专门化识别器类,在实际开始触摸时读取并保留视图中的位置,并改用专门化。 请注意下面的内容,我们为此目的如何定义一个初始位置视图属性。 (不过,如果要在框架之外使用它们,则需要将类和属性公开 。)

 导入UIKit.UIGestureRecognizerSubclass 
class DraggingPanGestureRecognizer:UIPanGestureRecognizer
{
var locationInViewWhenDraggingStarted = CGPoint.zero
覆盖func touchesBegan(_ touches:设置,事件:UIEvent){
super.touchesBegan(touches,with:event)
locationInViewWhenDragStarted =位置(在:视图中)
}
}

最后,这是显示如何使用新服务的客户端代码:

  @IBAction函数泛(_识别器:DraggingPanGestureRecognizer){ 
切换识别器状态{
案例。开始:
让点= ogniser.locationInViewWhenDraggingStarted
beginDragging位于 :点)
情况已更改:
让点= identifier.location(在:ognitor.view)
ContinueDragging :point)
...
}
}

和/或,如果您需要类似的实现来进行macOS开发(例如),即从NSPanGestureRecognizer继承,这里我们再做一次(但请注意,客户端代码与上面的代码完全相同,因此在下面不再赘述):

 导入AppKit类DraggingPanGestureRecognizer: 
NSPanGestureRecognizer {
var locationInViewWhenDraggingStarted = NSPoint.zero
覆盖func mouseDown(带有事件:NSEvent){
super.mouseDown(with:event)
locationInViewWhenDraggingStarted =位置(在:视图中)
}
}