Question

I have four UIGestureSwipeRecognizers registered (one for each direction), and they work as intended on an iPhone 4/4S (iOS 4.3 and 5) and iPad 1/2 (iOS 4.NotSure and 5). It is a game, so the only allowed device orientations are LandscapeRight and LandscapeLeft. However, on an iPhone 3G with iOS 4.1, the swipe recognizers respond as if the device were being held in Portrait. In other words, on the iPhone 3G, what should be an Up swipe in LandscapeLeft gets registered as a Right swipe. In fact, all four swipe recognizers behave as if the device were in Portrait; however, I have checked [[UIDevice currentDevice] orientation] and it always returns UIDeviceOrientationLandscapeLeft

Also, the app is a game built upon the cocos2d 1.0.1 template.

What could I be doing wrong?

Here's my code where I register the four swipe recognizers:

_swipeRecognizer_right = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeRightDetected)];
_swipeRecognizer_right.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:_swipeRecognizer_right];
_swipeRecognizer_right.delegate = self;

_swipeRecognizer_left = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeLeftDetected)];
_swipeRecognizer_left.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:_swipeRecognizer_left];
_swipeRecognizer_left.delegate = self;

_swipeRecognizer_up = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeUpDetected)];
_swipeRecognizer_up.direction = UISwipeGestureRecognizerDirectionUp;
[self.view addGestureRecognizer:_swipeRecognizer_up];
_swipeRecognizer_up.delegate = self;

_swipeRecognizer_down = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeDownDetected)];
_swipeRecognizer_down.direction = UISwipeGestureRecognizerDirectionDown;
[self.view addGestureRecognizer:_swipeRecognizer_down];
_swipeRecognizer_down.delegate = self;
Was it helpful?

Solution

There's no way around it other than converting the directions. I've done this in Kobold2D's swipe gesture recognizer using this internal method, it should be easy to adapt:

-(KKSwipeGestureDirection) convertSwipeDirection:(UISwipeGestureRecognizerDirection)uiDirection
{
    // portrait mode direction remains unchanged
    KKSwipeGestureDirection direction = (KKSwipeGestureDirection)uiDirection;

    switch (uiDirection)
    {
        case UISwipeGestureRecognizerDirectionRight:
        {
            switch (director.deviceOrientation)
            {
                case CCDeviceOrientationPortraitUpsideDown:
                    direction = KKSwipeGestureDirectionLeft;
                    break;
                case CCDeviceOrientationLandscapeLeft:
                    direction = KKSwipeGestureDirectionUp;
                    break;
                case CCDeviceOrientationLandscapeRight:
                    direction = KKSwipeGestureDirectionDown;
                    break;
                default:
                    break;
            }
            break;
        }

        case UISwipeGestureRecognizerDirectionLeft:
        {
            switch (director.deviceOrientation)
            {
                case CCDeviceOrientationPortraitUpsideDown:
                    direction = KKSwipeGestureDirectionRight;
                    break;
                case CCDeviceOrientationLandscapeLeft:
                    direction = KKSwipeGestureDirectionDown;
                    break;
                case CCDeviceOrientationLandscapeRight:
                    direction = KKSwipeGestureDirectionUp;
                    break;
                default:
                    break;
            }
            break;
        }

        case UISwipeGestureRecognizerDirectionUp:
        {
            switch (director.deviceOrientation)
            {
                case CCDeviceOrientationPortraitUpsideDown:
                    direction = KKSwipeGestureDirectionDown;
                    break;
                case CCDeviceOrientationLandscapeLeft:
                    direction = KKSwipeGestureDirectionLeft;
                    break;
                case CCDeviceOrientationLandscapeRight:
                    direction = KKSwipeGestureDirectionRight;
                    break;
                default:
                    break;
            }
            break;
        }

        case UISwipeGestureRecognizerDirectionDown:
        {
            switch (director.deviceOrientation)
            {
                case CCDeviceOrientationPortraitUpsideDown:
                    direction = KKSwipeGestureDirectionUp;
                    break;
                case CCDeviceOrientationLandscapeLeft:
                    direction = KKSwipeGestureDirectionRight;
                    break;
                case CCDeviceOrientationLandscapeRight:
                    direction = KKSwipeGestureDirectionLeft;
                    break;
                default:
                    break;
            }
            break;
        }
    }

    return direction;
}

For those who are using Cocos2D 2.x you should know that CCDirector no longer has the deviceOrientation property. Instead you just get the orientation from UIDevice:

UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

Then just change all case labels by replacing the CC with the UI prefix, for example

case CCDeviceOrientationPortraitUpsideDown:

should be changed to:

case UIDeviceOrientationPortraitUpsideDown:

OTHER TIPS

I've converted the function provided by @LearnCocos2D to Cocos2d-iphone only code (i.e. independent of Kobold2D):

- (UISwipeGestureRecognizerDirection) convertSwipeDirection:(UISwipeGestureRecognizerDirection)uiDirection
{
    // portrait mode direction remains unchanged
    UISwipeGestureRecognizerDirection direction = (UISwipeGestureRecognizerDirection)uiDirection;

    // Get cocod2d device orientation
    ccDeviceOrientation deviceOrientation = [[CCDirector sharedDirector] deviceOrientation];

    switch (uiDirection)
    {
        case UISwipeGestureRecognizerDirectionRight:
        {
            switch (deviceOrientation)
            {
                case CCDeviceOrientationPortraitUpsideDown:
                    direction = UISwipeGestureRecognizerDirectionLeft;
                    break;
                case CCDeviceOrientationLandscapeLeft:
                    direction = UISwipeGestureRecognizerDirectionUp;
                    break;
                case CCDeviceOrientationLandscapeRight:
                    direction = UISwipeGestureRecognizerDirectionDown;
                    break;
                default:
                    break;
            }
            break;
        }

        case UISwipeGestureRecognizerDirectionLeft:
        {
            switch (deviceOrientation)
            {
                case CCDeviceOrientationPortraitUpsideDown:
                    direction = UISwipeGestureRecognizerDirectionRight;
                    break;
                case CCDeviceOrientationLandscapeLeft:
                    direction = UISwipeGestureRecognizerDirectionDown;
                    break;
                case CCDeviceOrientationLandscapeRight:
                    direction = UISwipeGestureRecognizerDirectionUp;
                    break;
                default:
                    break;
            }
            break;
        }

        case UISwipeGestureRecognizerDirectionUp:
        {
            switch (deviceOrientation)
            {
                case CCDeviceOrientationPortraitUpsideDown:
                    direction = UISwipeGestureRecognizerDirectionDown;
                    break;
                case CCDeviceOrientationLandscapeLeft:
                    direction = UISwipeGestureRecognizerDirectionLeft;
                    break;
                case CCDeviceOrientationLandscapeRight:
                    direction = UISwipeGestureRecognizerDirectionRight;
                    break;
                default:
                    break;
            }
            break;
        }

        case UISwipeGestureRecognizerDirectionDown:
        {
            switch (deviceOrientation)
            {
                case CCDeviceOrientationPortraitUpsideDown:
                    direction = UISwipeGestureRecognizerDirectionUp;
                    break;
                case CCDeviceOrientationLandscapeLeft:
                    direction = UISwipeGestureRecognizerDirectionRight;
                    break;
                case CCDeviceOrientationLandscapeRight:
                    direction = UISwipeGestureRecognizerDirectionLeft;
                    break;
                default:
                    break;
            }
            break;
        }
    }

    return direction;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top