Why in iOS 8 my app at launch take wrong orientation?
Asked Answered
P

8

24

my app up to iOS 7 works correctly. I tried it today with Xcode 6 and when I run it I have a nasty surprise :(:

enter image description here You can see that Xcode now draw my viewController as if it is in portrait mode but as you can see is in landscape mode.

Do you know what is changed in iOS 8? :/ I used the following orientation methods:

  • (NSUInteger)supportedInterfaceOrientations
  • (BOOL)shouldAutorotate
  • (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation

EDIT:

I just discover this method:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window 
{
 return UIInterfaceOrientationMaskLandscape;
}

And now my first viewcontrollers works correctly :). the problem is when I show a modal (that change the set of method in UIInterfaceOrientationMaskAll) remake the ugly effect of screenshot. Precisely i change my methods in this mode:

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    if(self.restrictRotation)
    {
        return UIInterfaceOrientationMaskLandscape;
    }    
    else
    {
        return UIInterfaceOrientationMaskAll;
    }
}


// THIS IS A DELEGATE OF MODAL VIEW CONTROLLER
- (void)updateInterfaceAfterDocumentPreviewViewController
{
    NSLog(@"updateInterfaceAfterDocumentPreviewViewController");

    [[UIApplication sharedApplication]     setStatusBarOrientation:UIInterfaceOrientationLandscapeLeft];

    AppDelegate* appDelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
    appDelegate.restrictRotation = YES;
}
Poulard answered 15/9, 2014 at 17:27 Comment(5)
Try on a real device. Same problem?Joselynjoseph
Unfortunately yes :(Poulard
iOS 8 does not use autorotate and orientation API's anymore, as far as I know. Each orientation change is just an animated bounds change.Centeno
Thanks for you comment Legoless, see my answer to mc01 please.Poulard
I see this same thing in a number of third party apps (Reeder for example).Blakeslee
B
16

Please try the following code

In the didFinishLaunchingWithOptions of AppDelegate

self.window.rootViewController = self.viewController;

[self.window makeKeyAndVisible];

[self.window setFrame:[[UIScreen mainScreen] bounds]]; //Add
Bucko answered 30/9, 2014 at 7:38 Comment(0)
V
9

The issue seems to be the order of calls when you set up the window. You need to call makeKeyAndVisible before you assign the rootViewController in your didFinishLaunchingWithOptions method on the app delegate. The following works:

self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
[self.window makeKeyAndVisible];
self.window.rootViewController = self.myMainViewController;

But if you change the order to:

self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
self.window.rootViewController = self.myMainViewController;
[self.window makeKeyAndVisible];

You get the behavior you are experiencing.

Volcanic answered 7/10, 2014 at 3:14 Comment(2)
I had exactly the same issue. This solution worked for me. Thanks!Stromberg
Is this documented somewhere? it seems rather a bug to me, it works nevertheless.Vanderhoek
C
1

I had the same exact problem with a "Loading screen". This is what worked for me. (Please note: my App only supports iOS 7 or later, landscape mode.) :

    CGRect theFrame = self.view.frame;
    if ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.0) {
        CGRect screenBounds = [[UIScreen mainScreen] bounds];
        theFrame.origin = CGPointZero;
        theFrame.size.width = screenBounds.size.height;
        theFrame.size.height = screenBounds.size.width;
    }

    NSLog(@"%@", [NSNumber valueWithCGRect:theFrame]);
    self.loadingScreen = [[UIView alloc] initWithFrame:theFrame];

Please refer to Mike Hay's answer if your App supports portrait orientation and for the "long way to calculate the correct applicationFrame": https://mcmap.net/q/583311/-launching-app-in-landscape-mode

Hope this helps.

Commandeer answered 7/10, 2014 at 14:12 Comment(0)
G
1

Have a look at your .plist file.

  1. Make sure you have "Initial interface orientation" set as the orientation you wanted.
  2. In the "Supported interface orientations", have the preferred orientation as the first entry on the list (looks like apple changed this order).
Gerius answered 15/1, 2015 at 21:17 Comment(0)
U
1

I was having a similar problem, I couldn't get the right Launch Images to show (I had two for iPad, Default-Portrait.png and Default-Landscape.png) and I also couldn't get the App itself to auto orient after the Launch Image disappeared.

To solve the problem for the Launch Images:

  • Go to the Custom iOS Target Properties section of the project (Click on your Project's Icon at the top of the list of project files, and it should be the first section you see).
  • Add a row to that table called "Launch image" (should autofill) and enter "Default" as the string in the right column.
  • Make sure your Launch Images follow Apple's filename guidelines (ie: Default-568@2x, Default@2x, etc) check this SO answer

To solve the app orientation issue at first ViewController:

  • Go to your projects plist file (should be "YourApp-Info.plist")
  • Add a row and enter "Supported interface orientations"
  • Add the orientations that your app supports
Unwearied answered 23/1, 2015 at 20:13 Comment(0)
J
0

That approach to detecting orientation was deprecated in iOS8 (but still allowed for now). It was replaced with the concept of Size Classes and Trait Collections.

(Oddly, I can't seem to find a Size Class Reference in Apple's docs online right now - would swear it was there before - maybe in XCode). See here for WWDC videos.

Anyway, there's a checkbox in Interface Builder that says "Use Size Classes." Could be you have that checked. Turn it off & see if that helps?

Jerk answered 15/9, 2014 at 17:50 Comment(3)
Nothing change :(. In my opinion it is a problem of UIWindow because if I set backgroundColor of my view I see always the black color of UIWindow. Also if I print the window's frame... it's correctPoulard
Hmm. Does it stay that way when you change simulator orientation between landscape & portrait? Or is it only when it starts running? Are you using Auto Layout? Maybe some constraint is to blame?Jerk
I don't use auto layout in this project, if I run the application in landscape mode the application works correctly, instead if I run the application in portrait mode the application is showed like the screenshot attached (has to be showed in landscape). If I change the device orientation in info.plist and put only landscape it works but I need also portrait to show a qlpreviewcontroller in both the orientations.Poulard
L
0

Oldschool solution:

BOOL portrait;
BOOL iOS8OrLater = ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0);
if (iOS8OrLater) {
    CGFloat height = CGRectGetHeight(self.view.frame);
    CGFloat width = CGRectGetWidth(self.view.frame);
    if (width / height > 1.0) {
        portrait = NO;
    } else {
        portrait = YES;
    }
} else {
    portrait = UIInterfaceOrientationIsPortrait(self.interfaceOrientation);
}
if(portrait) {
    [self layoutPortrait];
} else {
    [self layoutLandscape];
}

You can call this in viewWillLayoutSubviews

Ladylike answered 11/11, 2014 at 22:26 Comment(0)
A
0
UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation;

if( UIDeviceOrientationIsLandscape( currentOrientation ) )
{
    if( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad )
    {
        [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];

        // -- Fix for rotation issue for ios 8
        if( IS_IOS_8_OR_LATER )
        {
            UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard_iPad"
                                                                 bundle: nil];
            // -- Set frame of nav controller
            UINavigationController *nc = [storyboard instantiateViewControllerWithIdentifier:@"NavController"];

            self.window.rootViewController = nc;

            [self.window setFrame:[[UIScreen mainScreen] bounds]];

            // -- Set fame of home view controller
            UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"Home"];

            self.window.rootViewController = vc;

            [self.window makeKeyAndVisible];

            [self.window setFrame:[[UIScreen mainScreen] bounds]];
        }
    }
}
Adelladella answered 20/11, 2014 at 21:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.