Warm tip: This article is reproduced from serverfault.com, please click

Can I set a lag time in between touchesBegan in Swift?

发布于 2020-11-28 04:45:33

My app has multiple balls, but only can be moved at a time. My code below shows that at touchesBegan I set specific fields used in touchesMoved. Within touchesCancelled and touchesEnded I reset everything.

This is my first Swift app, but not my first program, I know users like to try and crash apps. So with two fingers I started touching multiple balls as fast as I could, and eventually, yes, I ran through touchesBegan on another ball before the first one could be set as the "moving" ball. Is there any lag property where I can make the iOS wait even 0.3 seconds between touchesBegan?

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?){
    guard let touch = touches.first else { return }
    let location = touch.location(in: self)
    let touchedNodes = self.nodes(at: location)
    for node in  touchedNodes{
        if let theNode = node as? MyBall {
            if theNode.nodeType == .ball, theNode.isMoving == false,
                (myGV.currentBall == nil) {
                    theNode.isMoving = true
                    theNode.zPosition += 1
                    myGV.currentBall = theNode
                }
            }
        }
      }

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?){
    guard touches.first != nil else { return }
    if let touch = touches.first, let node = myGV.currentBall, node.isMoving == true {
        let touchLocation = touch.location(in: self)
        node.position = touchLocation
        node.isMoving = true
        node.inSlot = false
    }
}
Questioner
LuisC329
Viewed
0
bg2b 2020-11-28 22:40:06

I think the natural thing is organize it around one individual active touch. In touchesMoved, touchesEnded, and touchesCancelled, ignore everything when there's no active touch, and ignore any touches that are not the active touch. In touchesBegan, ignore new touches if there's already an active touch. Finally, in touchesBegan, if there's no active touch and the touch is on a ball, that touch becomes the active one and that ball becomes the being-moved ball. Sketch:

// activeTouch is a UITouch?

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
  for touch in touches {
    if activeTouch == nil {
      // Look for a touched ball; if found set that as the moving ball
      // and set this touch as activeTouch
    }
  }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?){
  guard let active = activeTouch else { return }
  for touch in touches {
    if touch == active {
      // Do stuff with the moving ball
    }
  }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?){
  guard let active = activeTouch else { return }
  for touch in touches {
    if touch == active {
      // The moving ball stops moving, reset activeTouch to nil
    }
  }
}

// Probably touchesCancelled should be the same as touchesEnded, or
// maybe you'd want to move the ball back to the starting position;
// depends on your game.