MarkerPen
MarkerPen

Reputation: 101

Order of multiple touches in UIGestureRecognizer

It seems that there is no guarantee about the order in which UITouches appear when looping through a UIGestureRecognizer's method [locationOfTouch: inView:]. Specifically:

for (int i = 0; i < [recognizer numberOfTouches]; i++) {
  CGPoint point = [recognizer locationOfTouch:i inView:self];
  NSLog(@"[%d]: (%.1f, %.1f)", i, point.x, point.y);
}

One would think that point with index 0 would be the first UITouch, or the first that was released, but quite often the order of 2 touches is mixed up. Does anyone know how to test for the order of those events? Unfortunately there is no access to the UITouch objects themselves (with the timestamp).

Also, no guarantee is made in the documentation that the touches from -locationOfTouch:inView: will always be in a reliable order. Can anyone confirm or deny this?

Upvotes: 10

Views: 1553

Answers (3)

kervich
kervich

Reputation: 487

Why not iterating through UITouches sorted by timestamp?

Upvotes: 0

Felix M&#252;ller
Felix M&#252;ller

Reputation: 71

It seems like to me like want to track i.e. two fingers of two hands independently, instead of recognizing a concrete gesture which is the goal of a UIGestureRecognizer, as the name says. If that's what you want i'd rather implement the UIResponder methods:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesBegan:touches withEvent:event];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesMoved:touches withEvent:event];
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [super touchesEnded:touches withEvent:event];
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    [self touchesEnded:touches withEvent:event];
}

With this approach you really get a set of UITouch objects und can do advanced tracking.

Upvotes: 3

lemnar
lemnar

Reputation: 4053

You could try setting the recognizer's delegate property and implementing -gestureRecognizer:shouldReceiveTouch:. It should be called sequentially, and you can then hold on to the touches.

Upvotes: 4

Related Questions