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?
** 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)
}
}
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)
}
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)
}
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)
}
}
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.
In Swift 3,4
Identify touch pointer by its hash:
// SmallDraw
func pointerHashFromTouch(_ touch:UITouch) -> Int {
return Unmanaged.passUnretained(touch).toOpaque().hashValue
}
I am making a game similar to Fruit Ninja using Swift 2.0 in Xcode v7.0. However, in the touchesBegan, touchesMoved, and touchesCancelled override functions, I am getting the three following errors:
"Value of type 'Set' has no member 'anyObject'" comes up twice and
"Value of optional type 'Set' not unwrapped; did you mean to use "!" or "?"?" comes once.
Here is the code
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch = touches.anyObject() as UITouch
let location = touch.locationInNode(self)
activeSlicePoints.append(location)
redrawActiveSlice()
activeSliceBG.removeAllActions()
activeSliceFG.removeAllActions()
activeSliceBG.alpha = 1
activeSliceFG.alpha = 1
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch = touches.anyObject() as UITouch
let location = touch.locationInNode(self)
activeSlicePoints.append(location)
redrawActiveSlice()
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
activeSliceBG.runAction(SKAction.fadeOutWithDuration(0.25))
activeSliceFG.runAction(SKAction.fadeOutWithDuration(0.25))
}
override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
touchesEnded(touches, withEvent: event)
}
Here is an image of on what lines the errors appear
All help appreciated. Thanks in advance.
let touch = touches.first as? UITouch
This will get you the first touch object.
Use it like:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
if let touch = touches.first {
// ...
}
super.touchesBegan(touches, withEvent:event)
}
Well, I says on the lines changeColorTo(touch: touches.anyObject() as? UITouch)
this error "value of type "Set" has no member "anyObject"
How can I fix the problem?
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
changeColorTo(touch: touches.anyObject() as? UITouch)
}
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
changeColorTo(touch: touches.anyObject() as? UITouch)
}
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
changeColorTo(touch: touches.anyObject() as? UITouch)
}
func changeColorTo(touch touch: UITouch? ) {
if let contact = touch {
changeColorTo(point: contact.locationInView(self))
}
}
func changeColorTo(point point: CGPoint ) {
// Change the color model to the color displayed at the given view coordinate
if let color = colorModel {
let bounds = self.bounds
if bounds.contains(point) {
color.hue = Float((point.x-bounds.minX)/bounds.width*360)
color.saturation = Float((point.y-bounds.minY)/bounds.height*100)
}
}
}
Thanks in advance!
You should not pass UITouch set to CGPoint.
Try the below to solve the issues,
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
let touch = touches.anyObject()! as UITouch
let location = touch.locationInView(self)
changeColorTo(location)
}
func changeColorTo(point: CGPoint ) {
}
My code:
var location = CGPoint(x:0,y:0)
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch = touches.anyObject() as? UITouch
location = touch.locationInView(self.view)
Button.center = location
}
Gives an error on this line:
let touch = touches.anyObject() as? UITouch
How to fix it?
Try this : -
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
for touch in touches {
if let touch = touches.first as? UITouch {
if touch.tapCount == 2{
//Do Something here
}
}
}
}
try this
if let touch = touches.first as? UITouch
{
}
I am overriding:
override func touchesBegan(touches: NSSet, withEvent event: UIEvent)
in Swift.
I am wondering, is this correct for getting one touch point:
var touchPoint: CGPoint! = event.touchesForView(self)?.anyObject()?.locationInView(self)
Thanks in advance!
As of iOS 8.3, touchesBegan takes a touches parameter which is a Set<NSObject>. It's now Set<UITouch>. So, you would:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let point = touches.first?.location(in: view) else { return }
// use `point` here
}
In previous iOS versions, touchesBegan was defined as a NSSet parameter, as outlined in the question, so you would:
override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
if let touch = touches.anyObject() as? UITouch {
let touchPoint = touch.locationInView(view)
...
}
}