gpt4 book ai didi

ios - UIPinchGestureRecognizer 与 UILongTapGestureRecognizer 的无问题使用

转载 作者:搜寻专家 更新时间:2023-11-01 07:03:58 25 4
gpt4 key购买 nike

我需要同时使用 UILongTapGestureRecognizerUIPinchGestureRecognizer

不幸的是,UILongTapGestureRecognizer 的第一次触摸也将计入 PinchGestureRecognizer。因此,当按住 UILongTapGestureRecognizer 时,只需再触摸一次即可触发捏合识别器。一个用于长按手势,两个用于捏合。

有没有办法独立使用两者?我不想为我的 UIPinchGestureRecognizer 使用 UILongTapGestureRecognizer 的触摸。

这就是我启用同步劳动力的方式:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {

//Allowing
if (gestureRecognizer == zoom) && (otherGestureRecognizer == longTap) {
print("working while filming")
return true
}

return false
}

最佳答案

我认为您没有所需的工具,因此我建议您尝试创建自己的手势识别器。这并不是真的那么难,但不幸的是,您需要同时执行长按和捏合效果。

不要尝试覆盖 UIPinchGestureRecognizerUILongPressGestureRecognizer,因为它根本不起作用(或者如果您管理它,请分享您的发现)。所以直接使用 UIGestureRecognizer

因此,要开始使用长按手势识别器,我们需要跟踪用户在没有移动太多的情况下按下并按住足够长的时间。所以我们有:

var minimumPressDuration = UILongPressGestureRecognizer().minimumPressDuration
var allowableMovement = UILongPressGestureRecognizer().allowableMovement

现在需要覆盖触摸(这都在手势识别器的子类中):

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent) {
touchMoveDistance = 0.0 // Reset the movement to zero
previousLocation = touches.first?.location(in: view) // We need to save the previous location
longPressTimer = Timer.scheduledTimer(timeInterval: minimumPressDuration, target: self, selector: #selector(onTimer), userInfo: nil, repeats: false) // Initiate a none-repeating timer
if inProgress == false { // inProgress will return true when stati is either .began or .changed
super.touchesBegan(touches, with: event)
}
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent) {
if let newLocation = touches.first?.location(in: view), let previousLocation = previousLocation {
self.previousLocation = newLocation
touchMoveDistance += abs(previousLocation.y-newLocation.y) + abs(previousLocation.x-newLocation.x) // Don't worry about precision of this. We can't know the path between the 2 points anyway
}
if inProgress == false {
super.touchesMoved(touches, with: event)
}
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent) {
longPressTimer?.invalidate()
longPressTimer = nil
if inProgress {
state = .ended
}
super.touchesEnded(touches, with: event)

if self.isEnabled { // This will simply reset the gesture
self.isEnabled = false
self.isEnabled = true
}
}

override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent) {
longPressTimer?.invalidate()
longPressTimer = nil
if inProgress {
state = .ended
}
super.touchesCancelled(touches, with: event)

if self.isEnabled {
self.isEnabled = false
self.isEnabled = true
}
}

所以这些都是长按。计时器上发生的事情是:

@objc private func onTimer() {
longPressTimer?.invalidate()
longPressTimer = nil
if state == .possible {
state = .began
}
}

所以基本上,如果我们将状态更改为 .begin,我们就会触发手势,其余事件就会正常工作。这非常整洁。

不幸的是,这还远未结束,您将需要对其余代码进行一些尝试...

您将需要保留触摸(如果我没记错的话,相同的触摸将被报告为可比较的对象,直到用户抬起手指):

  1. 开始将触摸保存到私有(private)属性 longPressTouch
  2. 在长按成功的计时器上设置一个属性以指示长按确实触发了 didSucceedLongPress = true
  3. 开始检查是否可以添加另一个触摸,如果不能则取消手势 if longPressTouch != nil && didSucceedLongPress == false { cancel() }。或者允许它,这真的取决于你想要什么。
  4. 开始时,如果可以添加触摸,则将它们添加到数组中并保存它们的初始位置pinchTouches.append((touch: touch, initialPosition: touchPosition))
  5. 在触摸结束和取消时确保从数组中删除适当的触摸。如果取消长按,则取消事件(或不取消,再次选择)

所以这应该是您的捏合手势识别器所需的所有数据。由于所有事件都应该已经按照您需要的方式为您触发,您所需要的只是您的规模的计算值:

var pinchScale: CGFloat {
guard didSucceedLongPress, pinchTouches.count >= 2 else {
return 1.0 // Not having enough data yet
}
return distanceBetween(pinchTouches[0].touch, pinchTouches[1].touch)/distanceBetween(pinchTouches[0].initialPosition, pinchTouches[1].initialPosition) // Shouldn't be too hard to make
}

然后您需要检查一些边缘情况,例如:用户启动长按,使用 2 根手指捏合,添加第 3 根手指(忽略),移开第 2 根手指:如果不处理这个,您可能会有点跳跃,这可能是有意的,也可能不是有意的。我猜你可以取消手势,或者你可以以某种方式转换初始值以使跳跃消失。

祝你好运,如果你会实现这个并让我们知道它是如何进行的。

关于ios - UIPinchGestureRecognizer 与 UILongTapGestureRecognizer 的无问题使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49190749/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com