Detect when UIGestureRecognizer is up, down, left and right Cocos2d

39,873

Solution 1

Apparently each UISwipeGestureRecognizer can only detect the swipe in the given direction. Even though the direction flags could be OR'ed together the UISwipeGestureRecognizer ignores the additional flags.

The solution is to add one UISwipeGestureRecognizer for each direction you want the swipe gesture to be recognized, and set each recognizer's direction accordingly to either up, down, left and right. If you want to test for a swipe in any direction you'll have to add four UISwipeGestureRecognizers.

It's kind of odd but that's the only way it worked for me.

Solution 2

UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGesture:)];
swipeGesture.direction = UISwipeGestureRecognizerDirectionUp|UISwipeGestureRecognizerDirectionDown;
[self.gestureAreaView addGestureRecognizer:swipeGesture];
[swipeGesture release];

-(void)handleSwipeGesture:(UISwipeGestureRecognizer *) sender 
{
    //Gesture detect - swipe up/down , can't be recognized direction
}

or

UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGesture:)];
swipeGesture.direction = UISwipeGestureRecognizerDirectionUp;
[self.view addGestureRecognizer:swipeGesture];
[swipeGesture release];

UISwipeGestureRecognizer *swipeGesture2 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGesture:)];
swipeGesture2.direction = UISwipeGestureRecognizerDirectionDown;
[self.view addGestureRecognizer:swipeGesture2];
[swipeGesture2 release];

-(void)handleSwipeGesture:(UISwipeGestureRecognizer *) sender 
{
    //Gesture detect - swipe up/down , can be recognized direction
    if(sender.direction == UISwipeGestureRecognizerDirectionUp)
    {
    }
    else if(sender.direction == UISwipeGestureRecognizerDirectionDown)
    {
    }
}

Solution 3

Use a UIPanGestureRecogizer and detect the swipe directions you care about. see the UIPanGestureRecognizer documentation for details. -rrh

// add pan recognizer to the view when initialized
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panRecognized:)];
[panRecognizer setDelegate:self];
[self addGestureRecognizer:panRecognizer]; // add to the view you want to detect swipe on


-(void)panRecognized:(UIPanGestureRecognizer *)sender
{
    if (sender.state == UIGestureRecognizerStateBegan) {
        // you might want to do something at the start of the pan
    }

    CGPoint distance = [sender translationInView:self]; // get distance of pan/swipe in the view in which the gesture recognizer was added
    CGPoint velocity = [sender velocityInView:self]; // get velocity of pan/swipe in the view in which the gesture recognizer was added
    float usersSwipeSpeed = abs(velocity.x); // use this if you need to move an object at a speed that matches the users swipe speed
    NSLog(@"swipe speed:%f", usersSwipeSpeed);
    if (sender.state == UIGestureRecognizerStateEnded) {
        [sender cancelsTouchesInView]; // you may or may not need this - check documentation if unsure
        if (distance.x > 0) { // right
            NSLog(@"user swiped right");
        } else if (distance.x < 0) { //left
            NSLog(@"user swiped left");
        }
        if (distance.y > 0) { // down
            NSLog(@"user swiped down");
        } else if (distance.y < 0) { //up
            NSLog(@"user swiped up");
        }
        // Note: if you don't want both axis directions to be triggered (i.e. up and right) you can add a tolerence instead of checking the distance against 0 you could check for greater and less than 50 or 100, etc.
    }
}

Solution 4

The defaut direction is UISwipeGestureRecognizerDirectionRight. the multiple directions also can be specified like that :

[swipeGesture setDirection: UISwipeGestureRecognizerDirectionRight|UISwipeGestureRecognizerDirectionLeft];

/// But if you want to get every single direction ,like that:

 UISwipeGestureRecognizer *swipeGestureR = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGestureRight:)];
[swipeGestureR setDirection: UISwipeGestureRecognizerDirectionRight ];
 [[[CCDirector sharedDirector] openGLView] addGestureRecognizer:swipeGestureR];

[swipeGestureR release];

UISwipeGestureRecognizer *swipeGestureL = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGestureLeft:)];
[swipeGestureL setDirection: UISwipeGestureRecognizerDirectionLeft];
[[[CCDirector sharedDirector] openGLView] addGestureRecognizer:swipeGestureL];

[swipeGestureL release];

the function handleSwipeGestureLeft will be called when swipe to left,and handleSwipeGestureRight wil be called when you swipe to right

Solution 5

Add one UISwipeGestureRecognizer for each axe (horizontal and vertical):

UISwipeGestureRecognizer *horizontalSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(action)];
[horizontalSwipe setDirection:(UISwipeGestureRecognizerDirectionRight |
                           UISwipeGestureRecognizerDirectionLeft )];

[self.view addGestureRecognizer:horizontalSwipe];

UISwipeGestureRecognizer *verticalSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(action)];
[verticalSwipe setDirection:(UISwipeGestureRecognizerDirectionUp |
                     UISwipeGestureRecognizerDirectionDown )];

[self.view addGestureRecognizer:verticalSwipe];
Share:
39,873

Related videos on Youtube

Magnus
Author by

Magnus

Updated on March 12, 2020

Comments

  • Magnus
    Magnus about 4 years

    I have a CCSprite that I want to move around using gestures. Problem is I'm completely new to Cocos2D. I want my sprite to perform one action when the gesture is up, another one when gesture is down, another action when gesture is right and same thing for left. Can someone point me in the right direction?

    Thanks!

  • Magnus
    Magnus over 12 years
    I added this, but it only detects when the direction is right. I added the gesture like this: -(void)addGesture { UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeGesture:)]; [[[CCDirector sharedDirector] openGLView] addGestureRecognizer:swipeGesture]; [swipeGesture release]; }
  • Zigglzworth
    Zigglzworth over 12 years
    Put NSLog("Gesture direction: %@", sender.direction); at the start of the -(void)handleSwipeGesture method and see what you get when you swipe in all directions... its strange that it only recognizes right.
  • Magnus
    Magnus over 12 years
    If I NSLog it, the output is: 1 which is the value for right. Is there any other way to detect gestures in cocos2d ?
  • j0k
    j0k over 11 years
    Thanks for posting an answer! While a code snippet could answer the question it's still great to add some addition information around, like explain, etc ..
  • S'pht'Kr
    S'pht'Kr over 10 years
    Interesting solution, but it bears mentioning that a big part of the point of UIGestureRecognizer and its subclasses is to standardize the way gestures are implemented... your code includes and suggests using your own logic to discriminate between swipes of different directions, speeds, etc. which means you run the risk of having a gesture implementation that "feels different" from the one people are used to in iOS. That said, this may be a good way for some cases, such as when you want to make the swiped/panned object move while being swiped.
  • Alex the Ukrainian
    Alex the Ukrainian over 10 years
    That does work great if you only need swipes. If you need to recognize swipes and a pan at the same time, see my answer here: stackoverflow.com/questions/8181774/…
  • Nishant
    Nishant about 8 years
    gesture.direction is RIGHT by default, thats why you are getting only RIGHT (1).