views:

2449

answers:

6

Hey guys,

I'm trying to differentiate between two (or more) UITouch objects on the iPhone. Specifically, I'd like to know the order in which the touches occurred.

For instance, in my -touchesBegan:withEvent: method I get an NSSet of UITouch objects. Now I can find out how many touches there are, but, which object represents which finger?

I notice the timestamp property on UITouch - is this what I'm looking for? I see how that would be useful to obtaining the last or first touch - providing the touches don't mutate...

Therein lies my problem. I can use the timestamp to single out the latest touch, but then the touch that occurred first moves, and IT becomes the latest touch...

At the end of this exercise, I'd like to be able to implement the "pinch" gesture to zoom in or out, etc.

Any help would be greatly appreciated, thanks.

+1  A: 

The often-discussed solution is to watch the events and compare the current x and y and previous x and y values to match them up. There seem to be some tricks though. Events can come out of order, and I've seen cases where it looked like the hardware or OS was getting confused with lots of (10) moving fingers.

A few people pointed out that the touch events are reused and you can use that fact to keep track of which finger is which. This has been covered at least once on StackOverflow, I believe.

Nosredna
+2  A: 

I've got some touch sample code here:

http://github.com/kailoa/6tringle-touchsamplecode/tree/master http://6tringle.com/blog/2009/TouchSampleCode.html

It's been useful to some people, and I think it might help you out.

Take a look at the NSMutableArray *ActiveTouches . It's the collection I use to keep track of the order in which touches occur.

There is an example of pinch and stretch in that code base the uses that array.

Kailoa Kadano
Thanks, I'll take a look when I get some time.
Jasarien
How is the activeTouches array different from what the system keeps for you in [event touchesForView:self]?
dk
+8  A: 

Each finger gets one UITouch object, and the same object is given to you again and again. Simply remember the pointers to set of initial UITouch objects, and do a pointer comparison to keep track of fingers.

From Apple's reference docs:

A touch object is persistent for a given finger during a sequence, and UIKit mutates it as it tracks the finger throughout it. The touch attributes that change are the phase of the touch, its location in a view, its previous location, and its timestamp. Event-handling code evaluates these attributes to determine how to respond to the event.

Dave R
+1  A: 

Hi I had a look at the Kailoa Kadano's code. You basically keep a NSMutableArray of current UITouch objects. However the documentation of UITouch states this:

A UITouch object is persistent throughout a multi-touch sequence. You should never retain an UITouch object when handling an event. If you need to keep information about a touch from one phase to another, you should copy that information from the UITouch object.

I don't quite see the reason for not retaining it if you release it again when the event finished but that's what the SDK doc says.

Ben
A: 

I was looking for the same info. And yes it appears you're not suppose to retain the UITouch data. According to the "Handling a Complex Multi-Touch Sequence" section of this Apple Developer Documentation, the "proper" way to track multiple touches is by the pointer value of the UITouch event.

Danny Sung