views:

1178

answers:

4

I need to catch two different swipping gestures using UISwipeGestureRecognizer(for example, UISwipeGestureRecognizerDirectionRight and UISwipeGestureRecognizerDirectionLeft). When I add two different recognisers with addGestureRecognizer method, only last added recognizer works. I've read that I need to implement gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: method of UIGestureRecognizerDelegate protocol, but nothing works.

Can anyone help with simple example of catching two or more same gestures? Thanks!

A: 

I would suggest you read a little bit on the technique that the gesture recognizers use to recognize the gesture. I suppose, the first recognizer tries to recognize the gesture, but realizes that he does not has to respond to it and then somehow he does not pass it on.

It's very useful to read how they work in order to understand how to use them.

Hope this helps.

Tomen
I think so, and there is such information on developer.apple.com :"By default, no two gesture recognizers can attempt to recognize their gestures simultaneously. But you can change this behavior by implementing gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:, an optional method of the UIGestureRecognizerDelegate protocol. This method is called when the recognition of the receiving gesture recognizer would block the operation of the specified gesture recognizer, or vice versa. Return YES to allow both gesture recognizers to recognize their gestures simultaneously."
A: 
+1  A: 

Um, a quick look at the documentation would reveal that you are doing way more work than you need to:

"direction The permitted directions of the swipe.

@property(nonatomic) UISwipeGestureRecognizerDirection direction

Discussion You may specify multiple directions by specifying multiple UISwipeGestureRecognizerDirection constants using bitwise-OR operands. The default direction is UISwipeGestureRecognizerDirectionRight."

Which is to say, instead of using two UISwipeGestureRecognizers, you can just do the following:

UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc]
                                      initWithTarget:self action:@selector(handleSwipeGesture:)];

 swipeGesture.direction = UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionLeft;

And in your action method:

 -(IBAction)handleSwipeGesture:(UISwipeGestureRecognizer*)sender
 {
 if (sender.direction == UISwipeGestureRecognizerDirectionLeft) {

     //do left action

 } else {

     //do right action

 }

}

Much simpler, and much less prone to conflict.

Phoenix
Commenter below is correct. This won't work as advertised. I should have checked my work more carefully! I blame solar flares knocking out my brain waves... Yeah, that's it, solar flares... or something...
Phoenix
+1  A: 

The answer: "Um, a quick look at the documentation..." from Phoenix absolutely will not work!

He is setting a mask, then using the same variable to test as if the recognizer cleared it and set a single bit. It stores, as he correctly quoted from the documentation:

The permitted directions of the swipe

sender.direction

will simply return the mask you set initially and in his example, will never resolve to a single direction!

UISwipeGestureRecognizerDirectionRight == 1
UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionLeft == 3

Additionaly, for most cases you don't need to:

  • setup a delegate
  • permit simultaneous gesture recognition (unless you want simultaneous swipes; not likely)
  • send the recognizer to the selector

The following works for me:

   UISwipeGestureRecognizer* swipe;

   swipe = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeL)] autorelease];
   swipe.direction = UISwipeGestureRecognizerDirectionLeft;
   [view addGestureRecognizer:swipe];

   swipe = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeR)] autorelease];
   swipe.direction = UISwipeGestureRecognizerDirectionRight; // default
   [view addGestureRecognizer:swipe];
ironmonkey