11
votes

I just opened my iPad project on XCode 4.5. My app is designed to run in Landscape mode. It works perfectly on previous versions of XCode. But on XCode 4.5, it is rotated of 90° (quarter turn) with a empty area on the right side of the screen (and my view has the correct size but goes out of the screen). It looks like this:

The view (red) rotated of 90° and going of the screen in landscape mode

I checked the following posts but didn't help:

orientation issue in ios6

ios6 Rotation issue from landscape to portrait mode

Set orientation to landscape mode in xcode 4.5 GM IOS 6

Anybody had this issue ?

Any help would be appreciated !

6
Check supported orientations in your info.plist.endy
in xcode go for iOS 5.1 simulator and check if it is working properly, if yes then there is some code to be done for making application compatible to iOS6, and please paste code you have used for orientation....P.J
Yes the app works well on iOS 5.1 iPad simulator. The problem occurs with iOS 6 iPad simulator (same problem of rotation as on device). I think that I am going to restart from a empty project and transfer my code and potentially recreate the xib... There will be some code to write as the former code to manage rotations is deprecated in iOS6. I will let you now... Thanks Apple for all this crazy work!!Regis_AG
How and where (which function) are you presenting this view controller?Steven Fisher
Has this question been resolved?lindon fox

6 Answers

6
votes

Thanks everybody for your replies. I finally found a solution.

First, check that all your launch images have the correct orientation and correct size in the target summary menu (blue icon of your project => target => summary => scroll at the bottom) ; if the size or orientation is not correct, you get a warning on the launch image which is not set properly.

Up to now, I had a project with this structure (old XCode fashion):

  • AppDelegate.h and .m
  • RootViewController.h and .m
  • a MainWindow-Iphone.xib and MainWindow-iPad.xib (with the RootViewController linked in Interface Builder ; see the screenshot below with the yellow/brown icon (with a square inside) relative to the RootViewController)

Here below a screenshot of what it looked like:

My old project structure

And here is what was the code in the applicationDidFinishLaunching: method of my AppDelegate:

- (void)applicationDidFinishLaunching:(UIApplication *)application {  

     [window addSubview:[rootViewController view]];
     [window makeKeyAndVisible];

}

What I did is to be closer to the structure you get when you create an empty project with XCode 4.5. Consequently:

  1. I removed the MainWindow.xib and MainWindow-iPad.xib and now created my window programatically (clearer and better to make sure that it fits the size of any screen)
  2. I removed the "Main nib file base name" and "Main nib file base name (iPad)" keys which were defined in my Info.plist (and set to MainWindow.xib and MainWindow-iPad.xib)
  3. I added empty RootViewController_iPhone.xib and RootViewController_iPad.xib
  4. I changed the code in my applicationDidFinishLaunching method like this:

    - (void)applicationDidFinishLaunching:(UIApplication *)application {    
    
    NSLog(@"applicationDidFinishLaunching");
    
     self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        self.rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController_iPhone" bundle:nil];
    } else {
        self.rootViewController = [[RootViewController alloc] initWithNibName:@"RootViewController_iPad" bundle:nil];
    }
    
    self.window.rootViewController = self.rootViewController;
    
    [self.window makeKeyAndVisible];
    

    }

And now, everything works fine ! Orientation is correct on iPad ! And it is much more clear than before :) I even didn't have to change the deprecated methods like

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

By the way, to make sure that all your views will be full screen (on iPhone 5) make sure that your views are set to the mode "Scale to fill" in Interface Builder and that "Autoresize subviews" is clicked. If some of your views do not scale to full screen, it is probably due to the order in which one you create your controllers/views (the superView sends a notification to its subviews only when it (the superView) is created). To solve this easily, simply add the following code in the - (void)viewDidLoad method:

CGRect screenBounds = [[UIScreen mainScreen] bounds];
    [self.view setFrame:CGRectMake(0,0,screenBounds.size.width,screenBounds.size.height)];

or use:

[self presentModalViewController:myViewController animated:TRUE];

instead of:

[self.view.superview addSubview:myViewController.view];

presentModalViewController indeed sends a resizing notification to the subviews.

Hope this will help !

4
votes

Make sure you are setting the window.rootViewController as well. I had the same issue, but this line fixed it for me:

MainViewController *mainView = [[MainViewController alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
window.rootViewController = mainView;
0
votes

I had a similar problem on an app I upgraded. I haven't found it documented but it seems there has been a change. What I ended up finding is the new window doesn't seem to know about rotation or size until after it is made key and visible. I was able to move my frame setting to immediately after makeKeyAndVisible and everything worked. I hope that helps you.

0
votes
[[yourViewController view] setFrame:CGRectMake(0.0, 0.0, 1024.0, 768.0)];
[[yourViewController view] setTransform:CGAffineTransformTranslate(CGAffineTransformMakeRotation(0.5*M_PI),128.0,128.0)];
0
votes

If you are using Storyboards one easy hack is to use the loadView method. It is called before viewDidLoad. Just go to your Storyboard and delete the associated view as you are going to create it programmatically in loadView. Then return to the view controller class and copy the following code:

- (void)loadView
{
    // You can adjust the view size and location here. If using full screen use the following code. If you have a tab bar for example and also want to account for the top default iPad bar, use: CGRectMake(0, 20, 1024, 699) instead.
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1024, 748)]; 
    view.backgroundColor = [UIColor whiteColor];
    view.autoresizesSubviews = NO;

    self.view = view;
}
0
votes

A few simple steps in order will solve this problem for you.

First, in AppDelegate.m, check if you're adding your rootViewController as a subView. That is, instead of this,

- (void)applicationDidFinishLaunching:(UIApplication *)application {  

 [window addSubview:[navigationController view]];
 [window makeKeyAndVisible];

 }

do something like this

- (void)applicationDidFinishLaunching:(UIApplication *)application {  

 window.rootViewController = navigationController;
 [window makeKeyAndVisible];

 }

if you're setting a navigation controller as your root view controller.

Second, if you need to get control of the rotation methods within your navigationController's pushed viewControllers, create a category for UINavigationController like so:

#import "UINavigationController+Rotation.h"

@implementation UINavigationController (Rotation)

- (BOOL)shouldAutorotate {

    BOOL result = self.topViewController.shouldAutorotate;

    return result;
}

- (NSUInteger)supportedInterfaceOrientations {

    return self.topViewController.supportedInterfaceOrientations;
}

@end

Now, these two orientation methods for iOS 6 upwards

-(BOOL)shouldAutorotate and
-(NSUInteger)supportedInterfaceOrientations

will get called within your classes.

This is necessary because the older rotation methods such as

-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

have been deprecated from iOS 6.

So lastly, you'll need to implement these in your view controllers; something like this:

-(BOOL)shouldAutorotate
    {
        return YES;
    }

-(NSUInteger)supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskAll;
}

if you want to allow your view controller to rotate and support all orientations.

The other orientation masks are:

  1. UIInterfaceOrientationMaskPortrait
  2. UIInterfaceOrientationMaskLandscapeLeft
  3. UIInterfaceOrientationMaskLandscapeRight
  4. UIInterfaceOrientationMaskPortraitUpsideDown
  5. UIInterfaceOrientationMaskLandscape and
  6. UIInterfaceOrientationMaskAllButUpsideDown