我試圖創建SKSpriteNode的子類,它可以檢測用戶交互(點擊,雙擊和按住),然後按照委託。這在我看來似乎是一種相對普遍的需求,但是:Swift SKSpriteNode:檢測Tap/DoubleTap/LongPress
- 該代碼無法檢測到雙擊而不觸發單擊。
- 我還沒有找到一種方法來檢測持有/長按操作。
我對這一切都錯了嗎?我不禁覺得SpriteKit應該有一些標準來處理如此基本的東西。我知道有UIGestureRecognizer,但它似乎與特定的SKNodes而不是UIViews兼容。
這是我目前的。根據來自蘋果的例子,我都在主類文件的非設備特定代碼:
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)
}
}
}
}
通常當我需要有檢測我用的是SKNode,它工作得更好,用戶點擊一個對象,我用了很多的問題, SKSpriteNode爲此。對於iOS特定的代碼,我將它添加到類本身,這也更好。 – Totka 2014-09-29 15:48:14
感謝Totka的回覆,但是你會不會在SKNode中面臨同樣的問題?你如何檢測雙擊和長時間而不是單擊?我擔心的是,也許我的代碼遠沒有確定這種基本用戶輸入的最佳做法。 – TheNeil 2014-09-29 15:50:33
我建議你使用內置的UIGestureRecognizers,因爲它們支持長時間按壓和雙擊(單抽頭抑制)。 – 0x141E 2014-10-01 08:05:28