从iPhone 6 Plus横屏主屏幕进入竖屏模式会导致方向错误。

58
这个问题的实际标题比我能够容纳的要长:在iPhone 6 Plus上启动一个只支持竖屏方向的根视图控制器的应用程序,但其他情况下支持横向方向,在主屏幕处于横向方向时会导致一种僵局状态,即应用程序窗口处于横向方向,但设备处于竖向方向。简而言之,它看起来像这样:

当它应该看起来像这样:

重现步骤:

  1. 运行iOS 8.0的iPhone 6 Plus。

  2. 一个支持除倒置竖屏方向以外所有方向的plist的应用程序。

  3. 应用程序的根视图控制器是UITabBarController。

  4. 所有内容,选项卡控制器及其所有后代子视图控制器都从supportedInterfaceOrientations返回UIInterfaceOrientationMaskPortrait。

  5. 从iOS主屏幕开始。

  6. 将设备旋转到横向方向(需要iPhone 6 Plus)。

  7. 冷启动应用程序。

  8. 结果:界面方向错误。

我想不出其他强制使用纵向方向的方法,除非完全禁用横向方向,但这是不可能的:我们的Web浏览器模态视图控制器需要横向方向。

我甚至尝试了子类化UITabBarController并覆盖supportedInterfaceOrientations以返回仅限纵向的掩码,但这(即使使用上述所有步骤)也无法解决问题。


这是一个链接,指向一个展示该bug的样例项目。



你是否已经向 Radar 提交了一个 bug 报告? - Pichirichi
Justin Miller在Apple论坛上建议如下:“您的信息属性列表应指定您愿意允许应用程序启动的方向(这应该对应于您的初始视图控制器支持的方向)。” - Pichirichi
我很喜欢你提问的方式。我一直在想该如何表达。感谢你帮我度过难关!!! - kirans_6891
13个回答

79

在 iPhone 6 Plus 上以横屏模式启动我们的应用程序时,我遇到了同样的问题。

我们的解决方法是通过项目设置从 plist 中删除支持横屏的接口方向:

Removed landscape orientation

然后在应用程序委托中实现 application:supportedInterfaceOrientationsForWindow: 方法:

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

显然,你的plist文件中的信息是用来指定你的应用程序可以启动的方向。


这对我很有帮助。该应用程序仅以允许的方向启动,但随后的视图控制器可以根据您的VC指定旋转到“除了倒置之外的所有方向”。谢谢! - Alfie Hanssen
哇!!!非常感谢!!!这对我非常有帮助:iPhone 6 Plus(设备或模拟器)。我必须支持画廊视图的所有旋转,但仅支持主视图的纵向。如果应用程序被启动,然后最小化,然后iPhone 6 Plus的主屏幕被旋转到横向,然后再次打开应用程序 - 一切看起来都是纵向的,但可以从两侧拉下/拉上通知中心/底部配置面板。(iOS警报也会旋转显示)… 这修复了问题! - Guntis Treulands
很好,谢谢你。我想知道为什么这只是6+的问题? - some_id
@Helium3 我怀疑这与6 Plus上的SpringBoard支持横屏有关。 - Stefan Church
这是正确的解决方案。 - Deepak Thakur
解决警报和操作表的问题。将主应用程序窗口保留在AppDelegate中,并为除此之外的所有窗口返回默认(.plist)设置。 return (window == self.window) ? UIInterfaceOrientationMaskAllButUpsideDown : [application supportedInterfaceOrientationsForWindow:window]; - Wisors

38

对于我来说,设置UIApplicationstatusBarOrientation似乎有效。我将其放置在应用委托中的application:didFinishLaunchingWithOptions:方法中。

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

    // the rest of the method
}

这对我有用,尽管我没有使用UITabBarController作为根视图控制器,其他答案认为这是原始帖子的主要问题。 - SeanR
1
如果您正在使用状态恢复,将此代码移至-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions会更好。 - Sonny Saluja
1
这太棒了。你救了我于水深火热之中。如果你在旧金山或附近,我会请你喝一杯啤酒。 - joeld
statusBarOrientation 是只读属性。苹果公司发出警告:iOS 9.0 中的 statusBarOrientation 设置器已被弃用:在 iOS 6.0 及更高版本中,显式设置状态栏方向的范围更小。但这是我摆脱错误的唯一方法。 - Nike Kov

6

使用UITabBarController作为根视图控制器时,iOS 8中似乎存在一个错误。解决方法是使用大多数基本的UIViewController作为根视图控制器。这个基本的视图控制器将作为您的选项卡栏控制器的父视图控制器:

///------------------------
/// Portrait-Only Container
///------------------------

@interface PortraitOnlyContainerViewController : UIViewController

@end

@implementation PortraitOnlyContainerViewController

- (NSUInteger)supportedInterfaceOrientations {
    return UIInterfaceOrientationMaskPortrait;
}

@end

// Elsewhere, in app did finish launching ...

PortraitOnlyContainerViewController *container = nil;

container = [[PortraitOnlyContainerViewController alloc] 
              initWithNibName:nil 
              bundle:nil];

[container addChildViewController:self.tabBarController];
self.tabBarController.view.frame = container.view.bounds;
[container.view addSubview:self.tabBarController.view];
[self.tabBarController didMoveToParentViewController:container];

[self.window setRootViewController:container];

很遗憾,这并不起作用。真正的解决方法是编辑 Plist 文件,使其在启动时与您的应用程序预期的行为相匹配。 - denvdancsk
@DJSK,你能否提供一个示例来说明如何做到这一点?我遇到了与我的UITabBarController类似的问题。我想支持所有方向,但应用程序只能在纵向方向打开。 - atulkhatri

2
我只想让我的应用程序在横屏模式下打开(并且不会在iPhone 6 Plus上出现您上面描述的问题),所以我在我的应用程序的PLIST文件中将横屏(左侧home键)横屏(右侧home键)设置为唯一允许的方向。这解决了应用程序打开时的方向问题。然而,我需要我的应用程序仅支持一个视图的纵向模式,因为我在应用程序中显示了一个UIImagePickerController,苹果要求在iPhone上必须以纵向模式显示它。
我能够仅支持该视图的纵向模式,同时保持我的应用程序在横屏模式下打开,通过在AppDelegate中包含以下代码:
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {

    if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {

        return UIInterfaceOrientationMaskAllButUpsideDown;

    } else {

        return UIInterfaceOrientationMaskAll;

    }

}

2

我是一个有用的助手,可以为您翻译文本。

我有一个非常类似的问题。我想在除了播放视频以外的所有地方都强制使用竖屏模式。

我的解决方法如下:

1)在AppDelegate中强制应用程序方向为竖屏:

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

2) 在我的情况下,启动一个空的模态视图控制器可以解决问题。我在导航视图控制器的根视图控制器(应用程序启动后第一个可见的视图控制器)的viewDidLoad中启动它:

- (void)showAndHideNamelessViewControllerToFixOrientation {
    UIViewController* viewController = [[UIViewController alloc] init];
    [self presentViewController:viewController animated:NO completion:nil];
    [viewController dismissViewControllerAnimated:NO completion:nil];
}

1
请尝试以下代码。可能是由于横向启动时键窗口的大小问题导致的。
// in application:didFinishLaunchingWithOptions: ...

self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
[self.window setFrame:[[UIScreen mainScreen] bounds]]; //<- ADD!!

不是的。请尝试查看文章末尾附带的示例项目。 - jaredsinclair
抱歉,我错过了示例项目。但是在 makeKeyAndVisible 之后强制设置窗口框架后,我成功让项目正常工作。 - fumiaki
这对我有用,而且我没有使用UITabBarController。谢谢! - bdmontz

1

很遗憾,Jared使用通用容器视图控制器的解决方法对我没有帮助。我已经尝试过通过支持接口方向来子类化选项卡栏控制器,但仍然没有成功。无论在启动后6+的方向如何,选项卡栏的窗口都会报告frame = (0 0; 736 414)

到目前为止,我唯一发现的解决方法是在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)));


这几乎可以工作。视图的方向在纵向显示正确,但状态栏仍然卡在横向。 - denvdancsk

1

我在我的应用程序中遇到了同样的错误,我通过这个solution解决了它。

起初它没有起作用,但经过一些挖掘,我必须在闪屏后的初始控制器上执行它。

答案是OjbC语言,让我更新为Swift。

override var shouldAutorotate: Bool {
    return true
}

override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
    return .portrait
}

不要忘记应该在初始视图控制器上执行此操作。

0
对于我自己而言,我遇到了与jaredsinclair相同的问题,但是通过子类化带有supportedInterfaceOrientations方法的UIViewController并不能解决这个问题。相反,我在我的AppDelegateappDidFinishLaunching方法中做了和他一样的事情,并将我的UITabBarController作为一个子视图添加到一个普通的UIViewController中,而不是他的子类,这样就解决了!

0

我在我的应用程序中遇到了类似的问题,它可以在横屏和竖屏下运行,并使用UITabBarController作为根视图控制器。

无论何时在横屏模式下启动应用程序,视图都会显示不正确。

解决方法如下: - 在XIB中删除根视图控制器的赋值。 - 在应用程序启动后手动添加它:


(void)applicationDidFinishLaunching:(UIApplication *)application { application.statusBarHidden = YES; [self.window setRootViewController:self.tabBarController]; }

问题已经解决。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接