混合使用UIGestureRecogniser和touchesBegan

时间:2016-01-11 19:26:28

标签: sprite-kit swift2 uigesturerecognizer touchesbegan

我在SpriteKit场景中同时使用UISwipeGestureRecognizertouchesBegan。 UISwipeGestureRecogniser在didMoveToView()

中启动
let swipeRight:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("swipedRight:"))
swipeRight.direction = .Right
view.addGestureRecognizer(swipeRight)

let swipeLeft:UISwipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: Selector("swipedLeft:"))
swipeLeft.direction = .Left
view.addGestureRecognizer(swipeLeft)

touchesBegan()用于在触摸节点时转换到另一个场景。节点由其名称标识,在某些情况下由其名称的前缀标识。

if (node.name?.hasPrefix("enemy") != nil) {
    let transition = SKTransition.crossFadeWithDuration(StandardSettings.SceneManager.transitionDuration)
    let enemyScene = EnemyScene(size: self.frame.size)
                    enemyScene.scaleMode = .AspectFill
    view?.presentScene(enemyScene, transition: transition)
}

最后,有swipedRight()和swipedLeft()的函数。这些将SKShapeNode从左向右移动(或反向移动)。

func swipedRight(sender:UISwipeGestureRecognizer) {            
shapeNode.runAction(SKAction.moveByX(UIScreen.mainScreen().bounds.size.width * 0.5, y: 0, duration: 5.0))
}

这一切都很有效,除非在滑动移动期间触摸由其前缀标识的节点。当没有与节点接触时,shapeNode按预期在屏幕上移动。当有联系时,也会调用到新场景的转换代码。似乎只有当敌人节点被其名称的前缀识别时才会发生这种情况。通过全名与字符串比较识别的节点不会出现此问题。有没有办法在代码执行滑动触发的方法时禁用touchesBegan()

2 个答案:

答案 0 :(得分:1)

确定触摸事件是滑动手势还是简单触摸的一种方法是测试起始触摸位置和结束触摸位置之间的距离。以下是如何执行此操作的示例。

首先,定义一个存储初始触摸位置的变量

var touchStart:CGPoint?

和一个常数来测试触摸位置之间的距离。根据需要调整此值。

let minSwipeDistance:CGFloat = 22

touchesBegan方法中,存储初始触摸位置

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if let touch = touches.first {
        touchStart = touch.locationInNode(self)
    }
}

并在touchesEnded中,比较当前触摸位置和初始触摸位置之间的距离。如果此距离相对较小,则不会轻扫该事件。

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if let touch = touches.first, start = touchStart {
        let location = touch.locationInNode(self)
        // Compute the distance between the two touches
        let dx = location.x - start.x
        let dy = location.y - start.y
        let distance = sqrt(dx*dx + dy*dy)
        if distance < minSwipeDistance {
            let node = nodeAtPoint(location)
            if let name = node.name where name.hasPrefix("enemy") {
                print ("transition to new scene")
            }
        }
    }
    // Reset the initial location
    touchStart = nil
}

答案 1 :(得分:0)

它来自Swift2的变化。在“旧”的swift中,我刚刚寻找节点的前缀... if (node.name?.hasPrefix("enemy"))随着升级到Swift2,我按照编辑器中推荐的更改添加了if (node.name?.hasPrefix("enemy") != nil)我现在明白了,这个有效地使前缀测试毫无意义。我使用的解决方案是强制声明if (node.name!.hasPrefix("enemy"))以及我需要确保现在所有SKNode都具有名称属性的警告。