3
votes

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?

1
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
@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
Yeah, just add another selector when the gesture is performed...Rui Peres

1 Answers

2
votes

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:)];