Get coordinates of multiple touches in Swift

2019-01-26 11:59发布

问题:

So I've been messing around trying to get the coordinates of touches on the screen. So far I can get the coordinates of one touch with this:

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    let touch = touches.anyObject()! as UITouch
    let location = touch.locationInView(self.view)
    println(location)
}

But when touching with two fingers I only get the coordinates of the first touch. Multi-touch works (I tested with this little tutorial: http://www.techotopia.com/index.php/An_Example_Swift_iOS_8_Touch,_Multitouch_and_Tap_Application). So my question is, how do I get the coordinates of the second (and third, fourth...) touch?

回答1:

** Updated to Swift 4 and Xcode 9 (8 Oct 2017) **

First of all, remember to enable multi-touch events by setting

self.view.isMultipleTouchEnabled = true

in your UIViewController's code, or using the appropriate storyboard option in Xcode:

Otherwise you'll always get a single touch in touchesBegan (see documentation here).

Then, inside touchesBegan, iterate over the set of touches to get their coordinates:

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


回答2:

the given touches argument is a set of detected touches. You only see one touch because you select one of the touches with :

touches.anyObject() // Selects a random object (touch) from the set

In order to get all touches iterate the given set

for obj in touches.allObjects {
   let touch = obj as UITouch
   let location = touch.locationInView(self.view)
   println(location)
}


回答3:

You have to iterate over the different touches. That way you can access every touch.

for touch in touches{
  //Handle touch
  let touchLocation = touch.locationInView(self.view)
}


回答4:

In Swift 1.2 this has changed, and touchesBegan now provides a Set of NSObjects. To iterate through them, cast the touches collection as a Set of UITouch objects as follows:

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {

    var touchSet = touches as! Set<UITouch>

    for touch in touchSet{
        let location = touch.locationInView(self.view)
        println(location)
    }
}


回答5:

For Swift 3, based on @Andrew's answer :

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

    let touchSet = touches

    for touch in touchSet{
        let location = touch.location(in: self.view)
        print(location)
    }
}

EDIT, My bad, that's not answering your question, had the same problem and someone linked me to this previous answer :

Anyway, I had to change few things to make it works in swift 3, here is my current code :

var fingers = [String?](repeating: nil, count:5)

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesBegan(touches, with: event)
    for touch in touches{
        let point = touch.location(in: self.view)
        for (index,finger)  in fingers.enumerated() {
            if finger == nil {
                fingers[index] = String(format: "%p", touch)
                print("finger \(index+1): x=\(point.x) , y=\(point.y)")
                break
            }
        }
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesMoved(touches, with: event)
    for touch in touches {
        let point = touch.location(in: self.view)
        for (index,finger) in fingers.enumerated() {
            if let finger = finger, finger == String(format: "%p", touch) {
                print("finger \(index+1): x=\(point.x) , y=\(point.y)")
                break
            }
        }
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesEnded(touches, with: event)
    for touch in touches {
        for (index,finger) in fingers.enumerated() {
            if let finger = finger, finger == String(format: "%p", touch) {
                fingers[index] = nil
                break
            }
        }
    }
}

I still have a little problem but I think it's linked to my GestureRecognizer in my code. But that should do the trick. It will print you the coordinate of each point in your consol.



回答6:

In Swift 3,4 Identify touch pointer by its hash:

// SmallDraw
func pointerHashFromTouch(_ touch:UITouch) -> Int {
    return Unmanaged.passUnretained(touch).toOpaque().hashValue
}