I am trying to create a subclass of SKSpriteNode that can detect user interaction (tap, double tap and hold) and then set aside for delegate. This seems to me a relatively common need, but:
- The code is not able to detect a double click without causing a single click.
- I did not find a way to detect hold / long-press actions at all.
Am I really doing all this wrong? I can't help but feel that SpriteKit needs to have something standard to handle something so simple. I know that UIGestureRecognizer, but it does not seem very compatible with certain SKNodes, and not with UIViews.
Here is what I have now. Based on Apple's examples, I have all the non-device code in the main class file:
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)
} else {
delegate.handleActionOnElement(self, actionType: ActionType.Double)
}
}
}
}