Swift SKSpriteNode:检测Tap / DoubleTap / LongPress

时间:2014-09-28 21:01:19

标签: ios user-interface swift sprite-kit skspritenode

我正在尝试创建SKSpriteNode的子类,它可以检测用户交互(点按,双击并按住),然后按照委托。在我看来,这似乎是一个相对普遍的需求,但是:

  1. 该代码无法在不触发单击的情况下检测到双击。
  2. 我根本没有找到一种检测保持/长按动作的方法。
  3. 我是否认为这一切都错了?我不禁觉得SpriteKit应该有一些标准来处理这么基本的东西。我知道有UIGestureRecognizer,但它似乎与特定的SKNode而不是UIViews非常兼容。

    这就是我目前所拥有的。基于Apple的示例,我在主类文件中包含了所有非设备特定的代码:

    import SpriteKit
    
    enum ActionType: Int {
        case Single
        case Double
        case Hold
    }
    
    protocol EnvironmentElementDelegate {
        func handleActionOnElement(element: EnvironmentElement, actionType: ActionType)
    }
    
    class EnvironmentElement: SKSpriteNode {
    
        let delegate: EnvironmentElementDelegate!
    
        init(imageNamed: String, elementNamed: String, delegate: EnvironmentElementDelegate) {
            self.delegate = delegate
            let texture = SKTexture(imageNamed: imageNamed)
            super.init(texture: texture, color: UIColor.clearColor(), size: texture.size())
            self.name = elementNamed
            userInteractionEnabled = true
        }
    
        required init(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
    }
    

    ...然后将所有特定于iOS的代码放在一个单独的扩展文件中:

    import SpriteKit
    
    extension EnvironmentElement {
    
        override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
            for touch: AnyObject in touches {
                if (touch.tapCount >= 2) {
                    NSObject.cancelPreviousPerformRequestsWithTarget(self)
                }
            }
        }
    
        override func touchesEnded(touches: NSSet, withEvent event: UIEvent) {
            for touch: AnyObject in touches {
                if (touch.tapCount == 1) {
                    delegate.handleActionOnElement(self, actionType: ActionType.Single)
                    // Unable to find Swift equivalent to this: [self performSelector:@selector(onFlip) withObject:nil afterDelay:0.3];
                } else {
                    delegate.handleActionOnElement(self, actionType: ActionType.Double)
                }
            }
        }
    }
    

2 个答案:

答案 0 :(得分:3)

我从来没有检测到双击,但如果我有,我会这样做:

1 - 添加一个名为alreadyTouch的本地var,并在初始化类时将其设置为false

2 - touchesBeginalreadyTouch false true将其设置为Timer否则请执行操作

3 - 设置0.2秒的本地alreadyTouch = true并将其添加到if else以检测触摸是否足够快。所以启动此计时器,您可以设置{{1}}。

希望有所帮助

答案 1 :(得分:3)

您只需在touch.tapCount

中使用touchesBegan:即可