Swift SpriteKit 3D Touch 和触摸移动

标签 swift touchesmoved 3dtouch

我最近将游戏的一个版本发送到 TestFlight 进行内部测试。 我的 friend 注意到他的 iPhone 6S Plus 上的拍摄控件无法正常工作。

控件如下

1) 屏幕左半边 = 跳转

2) 屏幕右半部分=拍摄

3) 滑动并按住屏幕右半部分=开始慢动作

现在,在我的触摸开始方法中,我的拍摄有轻微的延迟,因此如果调用触摸移动,它将取消拍摄并开始慢动作。 这似乎是在支持 3D Touch 的手机上导致问题的原因。

进一步深入研究,我发现了这篇文章

iOS 9 Spritekit Double Tap Not Working on iPhone 6S

它基本上指出,在启用 3D Touch 的设备上,触摸移动方法会自动调用。

  On 3D Touch capable devices, touch pressure changes cause     
   touchesMoved:withEvent: to be called for all apps running on iOS   
   9.0. When running iOS 9.1, the method is called only for apps  
   linked with the iOS 9.0 (or later) SDK.

    Apps should be prepared to receive touch move events with no   
    change in the x/y coordinates. "

这似乎可以解释为什么我的 friend 遇到问题,如果总是调用触摸移动,它将取消拍摄并开始慢动作,即使他没有在屏幕上滑动。

所以我的问题是

1) 可以在 SpriteKit 游戏中禁用 3D Touch 吗?

2)这是一个错误吗?

3) 还有其他方法可以在 3D Touch 设备上使用正确移动的触摸吗?

4)或者我可以使用手势识别器来模拟我当前在移动触摸中所做的滑动和保持功能。

感谢您的帮助

最佳答案

在尝试了各种其他不起作用的方法(包括 UISwipeGestureRecognizer 子类)之后,我终于找到了答案。

答案实际上就在我在问题中链接的同一个 stackOverflow 帖子中盯着我看

iOS 9 Spritekit Double Tap Not Working on iPhone 6S

解决方案是创建一个属性

var startingTouchLocation: CGPoint?

比接触开始你设置该属性

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    for touch in touches {
        let location = touch.locationInNode(self)

        /// Set starting touch. this is for 3d touch enabled devices, see touchesMoved method below
        startingTouchLocation = location


        ....
     }
 }

然后在touchesMoved中添加一个检查以从该方法返回,直到触摸实际移动为止。

 override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    for touch in touches {
        let location = touch.locationInNode(self)

        /// WAY 1 - Check if touch moved because on 3d touch devices this method gets called on a force touch.
        guard location != startingTouchLocation else { return }

        // Your code
        ...

        /// WAY 2 - Add a min distance for the finger to travel in any direction before calling touches moved code
        let minValue: CGFloat = 30
        guard let startingLocation = startingLocation else { return }

        guard currentLocation.y < startingLocation.y - minValue ||
        currentLocation.y > startingLocation.y + minValue ||
        currentLocation.x < startingLocation.x - minValue ||
        currentLocation.x > startingLocation.x + minValue else { return  false }

       // Your code 
       ....
     }
  }

关于Swift SpriteKit 3D Touch 和触摸移动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36060423/

相关文章:

swift - 在扩展 swift 中使用枚举作为字符串

ios - 应用程序关闭时 3D Touch UIapplicationShortcut 不起作用

ios - 多个 View 处理的触摸事件

ios - 将 touchesMoved 保持在 View Controller 的范围内

ios - `touchesBegan:withEvent:` 在屏幕左边缘延迟

ios - UICollectionView:测量单元格的点击力

ios - 在 setRegion 上取消选择 MKAnnotationView

ios - 升级到 XCode 9.1,命令/bin/sh 失败,退出代码 1 错误

ios - 理解 swift 3 中的平等?