0

I have an IOS application developed using Cocos2dx engine.

The application is locked for a specific orientation (for example portrait) everything in the application seems to work fine and according to the right orientation except for the recent apps bar and notifications which are according to the device orientation.

I want to be able to restrict it so it will have the same orientation as the application itself.

I noticed that removing the landscape orientation inside the info.plist file does the job, but I want to be able to do it through code.

In IOS 6 I found that all I had to was to override referredInterfaceOrientationForPresentation in my RootViewController and give the right orientation and this does the trick, but this method doesn't work for IOS 5 and below.

What do I need to do to make this work on devices with IOS 5 and below?

This is the code for the RootViewController (I didn't write it, I just added the last method and I'm trying to figure out how to fix the notifications and recent apps problem)

#include "cocos2d.h"

#import "RootViewController.h"
#import "AppDelegate.h"

#import "misc/deviceOrientation.h"
#import "services/ios/ConfigurationServiceImpl.h"

@implementation RootViewController
@synthesize progressView;
/*
 // The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
 - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
    // Custom initialization
    }
    return self;
 }
 */

/*
 // Implement loadView to create a view hierarchy programmatically, without using a nib.
 - (void)loadView {
 }
 */

/*
 // Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
 - (void)viewDidLoad {
    [super viewDidLoad];
 }
 */

-(NSUInteger)supportedInterfaceOrientations{

    ConfigurationServiceImpl* configurationService = [ConfigurationServiceImpl instance];
    if ([configurationService isLandscape])
        return UIInterfaceOrientationMaskLandscape;
    else
        return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
}

-(BOOL)shouldAutorotate{
    return YES;
}


// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {

//    printf("shouldAutorotateToInterfaceOrientation\n");

    //
    // There are 2 ways to support auto-rotation:
    //  - The OpenGL / cocos2d way
    //     - Faster, but doesn't rotate the UIKit objects
    //  - The ViewController way
    //    - A bit slower, but the UiKit objects are placed in the right place
    //

#if GAME_AUTOROTATION==kGameAutorotationNone
    //
    // EAGLView won't be autorotated.
    // Since this method should return YES in at least 1 orientation,
    // we return YES only in the Portrait orientation
    //
    return ( interfaceOrientation == UIInterfaceOrientationPortrait );
#elif GAME_AUTOROTATION==kGameAutorotationCCDirector
    //
    // EAGLView will be rotated by cocos2d
    //
    // Sample: Autorotate only in landscape mode
    //
    if( interfaceOrientation == UIInterfaceOrientationLandscapeLeft ) {
        [[CCDirector sharedDirector] setDeviceOrientation: kCCDeviceOrientationLandscapeRight];
    } else if( interfaceOrientation == UIInterfaceOrientationLandscapeRight) {
        [[CCDirector sharedDirector] setDeviceOrientation: kCCDeviceOrientationLandscapeLeft];
    }
}

    // Since this method should return YES in at least 1 orientation,
    // we return YES only in the Portrait orientation
    return ( interfaceOrientation == UIInterfaceOrientationPortrait );

#elif GAME_AUTOROTATION == kGameAutorotationUIViewController
    //
    // EAGLView will be rotated by the UIViewController
    //
    // Sample: Autorotate only in landscpe mode
    //
    // return YES for the supported orientations
    ConfigurationServiceImpl* configurationService = [ConfigurationServiceImpl instance];
    return [configurationService shouldAutorotateToInterfaceOrientation: interfaceOrientation];

#else
#error Unknown value in GAME_AUTOROTATION

#endif // GAME_AUTOROTATION


    // Shold not happen
    return NO;
}


 //This callback only will be called when GAME_AUTOROTATION == kGameAutorotationUIViewController

#if GAME_AUTOROTATION == kGameAutorotationUIViewController
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft)
        CDeviceOrientation::setDeviceOrientation(CDeviceOrientation::left);
    else if (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
        CDeviceOrientation::setDeviceOrientation(CDeviceOrientation::right);
    else if (toInterfaceOrientation == UIInterfaceOrientationPortrait)
        CDeviceOrientation::setDeviceOrientation(CDeviceOrientation::down);
    else if (toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown)
        CDeviceOrientation::setDeviceOrientation(CDeviceOrientation::up);
}
#endif // GAME_AUTOROTATION == kGameAutorotationUIViewController


- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];

    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}

- (void)dealloc {
    [super dealloc];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    ConfigurationServiceImpl* configurationService = [ConfigurationServiceImpl instance];
    if ([configurationService isLandscape])
        return UIInterfaceOrientationLandscapeRight;
    else
        return UIInterfaceOrientationPortrait;
}


@end
jessehouwing
  • 106,458
  • 22
  • 256
  • 341
Amit Ofer
  • 413
  • 1
  • 7
  • 26
  • 1. If the status bar and recent apps bar comes in different orientation, then iOS really isn't aware that you want to lock orientation, and 2. there [are](http://stackoverflow.com/questions/5838459/how-do-you-make-an-app-only-support-landscape) [numerous](http://stackoverflow.com/questions/6353076/make-app-start-and-remain-in-landscape-mode?rq=1) [questions](http://stackoverflow.com/questions/12630359/ios-6-how-do-i-restrict-some-views-to-portrait-and-allow-others-to-rotate) on this topic, care to elaborate on why your situation is different? – maroux Jul 08 '13 at 13:54
  • I tried everything written in other posts I found but nothing seemed to do the trick – Amit Ofer Jul 08 '13 at 14:40
  • Ok, so you have only one orientation listed in your apps Info.plist, you have implemented `shouldAutorotateToInterfaceOrientation` and `shouldAutoRotate` and `supportedInterfaceOrientations` in *every* view controller? Whether or not it's working after doing all that, this info (what all have you tried) needs to be in the OP. Help us help you, and the more info we have, the better/faster we can help you. – maroux Jul 08 '13 at 14:41
  • I have only one viewController as I'm using Cocos2dx for my application (game). my info.plist has 4 orientations, 2 for portrait and 2 for landscape, when I remove the 2 landscapes it solves my problem, but I'm looking for a solution that overrides the values of info.plist through code so I dont' have to touch info.plist (I have my reasons), thanks – Amit Ofer Jul 08 '13 at 14:49

2 Answers2

1

Use shouldAutorotateToInterfaceOrientation for iOS 5 and shouldAutorotate for iOS 6. In iOS5 method, use if case for your supported orientations and return YES for them. In your app summary, enable all the orientations. Hope these will help you.

Engnyl
  • 1,380
  • 16
  • 24
  • I tried shouldAutoRotate for IOS 6 and it didn't work, its currently returning YES, changing to NO had no effect on the recent apps bar. The thing that did the trick was to implement preferredInterfaceOrientationForPresentation to return UIInterfaceOrientationPortrait. but this does not work for ios 5 – Amit Ofer Jul 08 '13 at 14:40
  • Try to add supportedInterfaceOrientations method and return your orientation. – Engnyl Jul 08 '13 at 15:09
0

I make this code skeleton for dealing with wanted & unwanted devices orientations, in my case i want to ignore the UIDeviceOrientationUnknown, UIDeviceOrientationFaceUp and UIDeviceOrientationFaceDown, caching the last allowed orientation. This code deals with iPhone and iPad devices and can be useful for you.

- (void)modXibFromRotation {

UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];
NSString *device = [[UIDevice currentDevice]localizedModel];
UIInterfaceOrientation cachedOrientation = [self interfaceOrientation];

if ([device isEqualToString:@"iPad"]) {

    if (orientation == UIDeviceOrientationUnknown || 
        orientation == UIDeviceOrientationFaceUp || 
        orientation == UIDeviceOrientationFaceDown) {

            orientation = (UIDeviceOrientation)cachedOrientation;
    }

    if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight) {

        /* Your code */
    }

    if (orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationPortraitUpsideDown) {

        /* Your code */     
    }
}

if ([device isEqualToString:@"iPhone"] || [device isEqualToString:@"iPod"]) {

    if (orientation == UIDeviceOrientationUnknown || 
    orientation == UIDeviceOrientationFaceUp || 
    orientation == UIDeviceOrientationFaceDown) {

        orientation = (UIDeviceOrientation)cachedOrientation;
    }

    if (orientation == UIDeviceOrientationLandscapeLeft || orientation == UIDeviceOrientationLandscapeRight) {

         /* Your code */
    }

    if (orientation == UIDeviceOrientationPortrait || orientation == UIDeviceOrientationPortraitUpsideDown) {

        /* Your code */
    }
  }
}

Yo have to call this method from two places in your view controller:

Fist begin generating device Orientation Notifications in your App delegate:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.

//**** ADD THIS CODE *****
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];

// Add the main view controller's view to the window and display.
self.window.rootViewController = self.mainViewController;
[self.window makeKeyAndVisible];

return YES;

}

then listen for device Orientation Notifications in your view controller:

- (void)viewDidLoad {   

     [notificationCent addObserver:self
                          selector:@selector(modXibFromRotation)
                              name:UIDeviceOrientationDidChangeNotification object:nil];
}

Finally call the modXibFromRotation method from:

- (void)viewWillAppear:(BOOL)animated {

    [super viewWillAppear];

    [self modXibFromRotation];
}

This will call the check orientation method before the view is shown.

MarioGT
  • 632
  • 6
  • 8
  • - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { if (toInterfaceOrientation == UIInterfaceOrientationPortrait || toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown) { return YES; } else { return NO; } } The code above will let you orient in portrait and upside-down portrait mode in iOS 5. Writing your own method regarding the code I provide might help you. – Engnyl Jul 09 '13 at 14:24
  • I tried your code (without loading my config, just to test that it limits to portrait) it didn't do anything. When I run the game and the device is oriented in landscape, the game opens in portrait as it should but when I double click on the home button the recents apps still open in Landscape – Amit Ofer Jul 09 '13 at 15:09
  • Yo have to call this method from: - (void)viewWillAppear:(BOOL)animated {} and you can also listen for notifications from UIDeviceOrientationDidChangeNotification to trigger it. Works 100% in my proyects. – MarioGT Jul 09 '13 at 18:34
  • can you provide an example? – Amit Ofer Jul 10 '13 at 15:35
  • Check my answer again, I added more code for the implementation of my method – MarioGT Jul 10 '13 at 23:41