如何识别Swift中的连续触摸?

use*_*836 8 gesture-recognition sprite-kit swift

如何识别Swift代码中的连续用户触摸?连续我的意思是用户将手指放在屏幕上.只要用户触摸屏幕,我想将精灵套件节点移动到用户触摸的方向.

0x1*_*41E 19

基本步骤

  1. 存储触摸事件的位置(touchesBegan/ touchesMoved)
  2. 将精灵节点移向该位置(update)
  3. 不再检测到触摸时停止移动节点(touchesEnded)

这是一个如何做到这一点的例子

Xcode 8

let sprite = SKSpriteNode(color: SKColor.white, size: CGSize(width:32, height:32))
var touched:Bool = false
var location = CGPoint.zero

override func didMove(to view: SKView) {
    /* Add a sprite to the scene */
    sprite.position = CGPoint(x:0, y:0)
    self.addChild(sprite)
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    touched = true
    for touch in touches {
        location = touch.location(in:self)
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        location = touch.location(in: self)
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    // Stop node from moving to touch
    touched = false
}

override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered
    if (touched) {
        moveNodeToLocation()
    }
}

// Move the node to the location of the touch
func moveNodeToLocation() {
    // Compute vector components in direction of the touch
    var dx = location.x - sprite.position.x
    var dy = location.y - sprite.position.y
    // How fast to move the node. Adjust this as needed
    let speed:CGFloat = 0.25
    // Scale vector
    dx = dx * speed
    dy = dy * speed
    sprite.position = CGPoint(x:sprite.position.x+dx, y:sprite.position.y+dy)
}
Run Code Online (Sandbox Code Playgroud)

Xcode 7

let sprite = SKSpriteNode(color: SKColor.whiteColor(), size: CGSizeMake(32, 32))
var touched:Bool = false
var location = CGPointMake(0, 0)

override func didMoveToView(view: SKView) {
    self.scaleMode = .ResizeFill
    /* Add a sprite to the scene */
    sprite.position = CGPointMake(100, 100)
    self.addChild(sprite)
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    /* Start moving node to touch location */
    touched = true
    for touch in touches {
        location = touch.locationInNode(self)
    }
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    /* Update to new touch location */
    for touch in touches {
        location = touch.locationInNode(self)
    }
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    // Stop node from moving to touch
    touched = false
}

override func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */
    if (touched) {
        moveNodeToLocation()
    }
}

// Move the node to the location of the touch
func moveNodeToLocation() {
    // How fast to move the node
    let speed:CGFloat = 0.25
    // Compute vector components in direction of the touch
    var dx = location.x - sprite.position.x
    var dy = location.y - sprite.position.y
    // Scale vector
    dx = dx * speed
    dy = dy * speed
    sprite.position = CGPointMake(sprite.position.x+dx, sprite.position.y+dy)

}
Run Code Online (Sandbox Code Playgroud)


jon*_*our 12

这个过程最困难的事情是跟踪多点触控环境中的单个触摸.对此的"简单"解决方案的问题(即,打开"打开"并将touchesBegan其关闭touchesEnded)是如果用户触摸屏幕上的另一个手指然后提起它,它将取消第一次触摸的动作.

为了实现这种防弹,您需要跟踪其生命周期内的各个触摸.当第一次触摸发生时,您保存该触摸的位置并将对象移向该位置.应该将任何进一步的触摸与第一次触摸进行比较,如果它们不是第一次触摸则应该被忽略.这种方法还允许您处理多点触控,其中可以使对象朝向屏幕上当前的任何手指移动,然后如果第一个手指被抬起则移动到下一个手指,依此类推.

重要的是要注意,UITouch对象在touchesBegantouchesMoved,和之间是不变的touchesEnded.您可以将UITouch对象视为在其中创建touchesBegan,更改touchesMoved和销毁touchesEnded.您可以通过将触摸对象的引用保存到创建的字典或数组中来跟踪触摸过程中的相位touchesBegan,然后touchesMoved您可以检查任何现有触摸的新位置并更改对象的当然,如果用户移动他们的手指(您可以应用公差来防止抖动,例如,如果x/y距离小于某个公差,则不要改变路线).在touchesEnded您可以检查是否处于焦点中的触摸是结束了一个,并取消对象的移动,或将其设置为向其他任何的接触,仍然发生移动.这很重要,就像你只检查任何旧的触摸对象结束一样,这也会取消其他触摸,这会产生意想不到的结果.

这篇文章在Obj-C中,但代码很容易移植到Swift并向您展示您需要做什么,只需查看"处理复杂多点触控序列"下的内容:https://developer.apple.com/library /ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/multitouch_background/multitouch_background.html