3

I have two gesture recognizers that recognize a swipe right gesture and a long press gesture. I tried to use the delegate method gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer: but whenever I perform the swipe and long press gestures the method is called many times instead of once. I use the following code for setting up the gesture recognizers, calling the delegate method, and handling the gestures once they are performed.

//Setting up the swipe gesture recognizer
UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeRight:)];
swipeRight.direction = UISwipeGestureRecognizerDirectionRight; 
swipeRight.delegate = self;
[self addGestureRecognizer:swipeRight];

//Setting up the long press gesture recognizer
UILongPressGestureRecognizer *rightLongPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeRight:)];
rightLongPressRecognizer.delegate = self;
rightLongPressRecognizer.tag = PRESS_RIGHT_TAG;
[rightLongPressRecognizer setMinimumPressDuration:0.5];
[self addGestureRecognizer:rightLongPressRecognizer];

//Delegate method
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;   
}

//Method that the gestures call 
-(void)handleSwipeRight: (UIGestureRecognizer *)recognizer {

    self.player.direction = RIGHT;
    [self resetSpriteView];
    [self.playerSprite startAnimating];

    float playerSpriteX = self.playerSprite.center.x;
    float playerSpriteY = self.playerSprite.center.y;
    self.toPoint = CGPointMake(playerSpriteX + TILE_WIDTH, playerSpriteY);
    if(!([self checkIfPlayerHasReachedEnd])) {
        self.fromPoint = CGPointMake(playerSpriteX, playerSpriteY);
        CABasicAnimation *moveAnimation = [CABasicAnimation animation];
        moveAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(playerSpriteX + TILE_WIDTH, playerSpriteY)];
        [moveAnimation setDelegate:self];
        [moveAnimation setFillMode:kCAFillModeForwards];
        [moveAnimation setRemovedOnCompletion:NO];
        [moveAnimation setDuration:MOVE_ANIMATION_DURATION];
        [self.playerSprite.layer addAnimation:moveAnimation forKey:@"position"];
    }
}

Is there a better way to implement a swipe and hold gesture recognizer?

pasawaya
  • 11,515
  • 7
  • 53
  • 92
  • Why are you using the same method to handle both the gestures? It's normal it becomes more complex the handling if you that. – Rui Peres Apr 19 '13 at 20:35
  • @JackyBoy - Well I thought that I have to set a method for the gesture recognizer to work, so I wasn't sure what else to do. Is there a better way to do it? – pasawaya Apr 19 '13 at 20:37
  • Yeah, just add another selector when the gesture is performed... – Rui Peres Apr 19 '13 at 20:40

1 Answers1

2

I think here the problem is the mis-conception of what the delegate does, and what the method is called, when the gesture is performed, actually is, nothing else.

Handle the long press in another method:

UILongPressGestureRecognizer *rightLongPressRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];

And handle the swipe gesture in it's own:

UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeRight:)];
Rui Peres
  • 25,741
  • 9
  • 87
  • 137
  • Can you elaborate a little on this? What can I do to my code to fix my "mis-conception" of what the delegate does? Anyway, I appreciate the answer! – pasawaya Apr 19 '13 at 20:53
  • Thanks for the edit, but what would be done in `handleLongPress:` and `handleSwipeRight? Would they have the same implementation? – pasawaya Apr 19 '13 at 21:00
  • No, you now implement your own logic. What happens when the long press happens? What happens when the swipe right happens? That's up to you. – Rui Peres Apr 19 '13 at 21:04
  • I understand. But I need something to happen only when the user both swipes and holds. I don't want anything to happen if the user only long presses or if the user only swipes. – pasawaya Apr 19 '13 at 21:31
  • In that it's a different thing... You should check here: `-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer` – Rui Peres Apr 19 '13 at 21:34
  • The thing is, when you know that the both gestures have been done at the same time, you can disable both... You do what you have to do, and then re-enable them... `myGesture.enabled = NO;` – Rui Peres Apr 19 '13 at 21:38