Launching into portrait-orientation from an iPhone

2019-01-30 00:32发布

The actual title for this question is longer than I can possibly fit:

Launching an app whose root view controller only supports portrait-orientation but which otherwise supports landscape orientations on an iPhone 6 Plus while the home screen is in a landscape orientation results in a limbo state where the app's window is in a landscape orientation but the device is in a portrait orientation.

In short, it looks like this:

When it is supposed to look like this:

Steps to Reproduce:

  1. iPhone 6 Plus running iOS 8.0.

  2. An app whose plist supports all-but-portrait-upside-down orientations.

  3. The root view controller of the app is a UITabBarController.

  4. Everything, the tab bar controller and all its descendent child view controllers return UIInterfaceOrientationMaskPortrait from supportedInterfaceOrientations.

  5. Start at iOS home screen.

  6. Rotate to landscape orientation (requires iPhone 6 Plus).

  7. Cold-launch the app.

  8. Result: broken interface orientations.

I can't think of any other way to enforce a portrait orientation except to disable landscape altogether, which I can't do: our web browser modal view controllers need landscape.

I even tried subclassing UITabBarController and overriding supportedInterfaceOrientations to return the portrait-only mask, but this (even with all the other steps above) did not fix the issue.


Here's a link to a sample project showing the bug.


13条回答
Fickle 薄情
2楼-- · 2019-01-30 00:51

I'm in the same situation, and doing [self.window setFrame:...] doesn't work for me.

Adding the following at the end of application:didFinishLaunchingWithOptions is the only thing I've found that works. It makes the screen blink and isn't exactly clean and efficient.

I added this at the end of application:didFinishLaunchingWithOptions:

UIViewController *portraitViewController = [[UIViewController alloc] init];
UINavigationController* nc = [[UINavigationController alloc] initWithRootViewController:portraitViewController];
[self.navController presentViewController:nc animated:NO completion:nil];
[self.navController dismissViewControllerAnimated:NO completion:nil];  
[UIViewController attemptRotationToDeviceOrientation];
查看更多
来,给爷笑一个
3楼-- · 2019-01-30 00:59

I had a very similar problem. I wanted to force portrait mode everywhere except for playing back videos.

What I did was:

1) to force the app orientation to be in portrait in the AppDelegate:

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    if ([window.rootViewController.presentedViewController isKindOfClass:[MPMoviePlayerViewController class]])
    {
        return UIInterfaceOrientationMaskAll;
    }
    return UIInterfaceOrientationMaskPortrait;
}

2) launching an empty modal view controller fixed the problem in my case. I launch it in the viewDidLoad of the first view controller that is on the root of my NavigationViewController (the first view controller visible after the application launches):

- (void)showAndHideNamelessViewControllerToFixOrientation {
    UIViewController* viewController = [[UIViewController alloc] init];
    [self presentViewController:viewController animated:NO completion:nil];
    [viewController dismissViewControllerAnimated:NO completion:nil];
}
查看更多
SAY GOODBYE
4楼-- · 2019-01-30 01:01

No luck for me the workaround by Jared using a generic container view controller. I've already subclassed tab bar controller with supportedInterfaceOrientations with no luck as well. Regardless of orientation of the 6+ after launch the tab bar's window is reporting frame = (0 0; 736 414)

So far the only workaround I've found is to force the window frame after makeKeyAndVisible

[self.window makeKeyAndVisible]; self.window.frame = CGRectMake(0, 0, MIN(CGRectGetWidth(self.window.frame), CGRectGetHeight(self.window.frame)), MAX(CGRectGetWidth(self.window.frame), CGRectGetHeight(self.window.frame)));

查看更多
走好不送
5楼-- · 2019-01-30 01:01

I got same bug on my app, I figured it out with this solution

Firstly it didn't work but after some dig I have to do it on initial controller after splash screen.

Answer is OjbC language let me update it to Swift

override var shouldAutorotate: Bool {
    return true
}

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

Don't forget that should on the initial view controller.

查看更多
Deceive 欺骗
6楼-- · 2019-01-30 01:01

For myself, I was having the same issue as jaredsinclair, but subclassing a UIViewController with the supportedInterfaceOrientations method was not solving the issue. Instead I did exactly what he did in my appDidFinishLaunching method of my AppDelegate and added my UITabBarController as a child to a normal UIViewController rather than his subclass and it worked!

查看更多
成全新的幸福
7楼-- · 2019-01-30 01:02

Setting the statusBarOrientation of the UIApplication seems to work for me. I placed it in the application:didFinishLaunchingWithOptions: method in the app delegate.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    application.statusBarOrientation = UIInterfaceOrientationPortrait;

    // the rest of the method
}
查看更多
登录 后发表回答