UIWindow在使用横向方向时大小错误

我有一个空的应用程序,并没有介入故事板或xib。 我想有一个隐藏的状态栏,只支持横向。 再一次,我不想仅在代码内进行这些更改,也不要触摸Info.plist。

问题

我用一个控制器创build一个UIWindow,唯一支持的方向是横向。 在这种情况下,我的UIWindow创build在纵向模式的维度,不旋转。 预期的结果将是一个完全青色的屏幕。

破坏的UIWindow

这是我的代表:

#import "AppDelegate.h" #import "AppViewController.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; self.window.backgroundColor = [UIColor cyanColor]; self.window.rootViewController = [[AppViewController alloc] init]; [self.window makeKeyAndVisible]; return YES; } @end 

这是我的控制者:

 #import "AppViewController.h" @implementation AppViewController - (BOOL)shouldAutorotate { return YES; } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { return UIInterfaceOrientationLandscapeLeft; } - (BOOL)prefersStatusBarHidden { return YES; } - (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskLandscape; } @end 

到目前为止,我已经尝试过

如果我在调用makeKeyAndVisible之后设置了rootViewController,那么一切似乎都起作用了。

 self.window.backgroundColor = [UIColor cyanColor]; [self.window makeKeyAndVisible]; self.window.rootViewController = [[AppViewController alloc] init]; 

还有一些问题。 首先我不喜欢这个,因为它似乎很脆弱。 第二个问题是,在一个更复杂的应用程序中,将一个GLKViewController设置为rootViewController,我得到以下结果(预期在左边没有黑色区域):

破碎的GLKViewController

它看起来像状态栏不够隐藏。 几个手势识别器处于活动状态,并在GLKViewController中单击黑色区域,产生以下日志消息:

2014-09-25 13:20:42.170 StackOverflowExample [6971:107907] _UIApplicationHandleEventFromQueueEvent,_windowServerHitTestWindow:UIClassicWindow:0x7fa20b805e00; frame =(0 0; 375 667); userInteractionEnabled = NO; gestureRecognizers = NSArray:0x7fa20b80a620; layer = UIWindowLayer:0x7fa20b806890

我还进行了各种其他更改,如附加一个空的UIViewController并添加我的视图作为子视图。 在这种情况下,我的看法看起来是正确的,但窗口仍然使用错误的尺寸。

如果我不覆盖我的视图控制器supportedInterfaceOrientations方法,一切都旋转正确。 但那当然不是我想要的。

纵向模式运行横向应用程序时UIScreen在iOS 8中具有纵向边界(只有当您在应用程序切换面板中没有此应用程序时,由于iOS 8使某些caching)。 即使使用makeKeyAndVisible显示窗口也不会改变它的框架。 但它根据AppViewController可用方向更改[UIScreen mainScreen].bounds

 #import "AppDelegate.h" #import "AppViewController.h" @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Portrait bounds at this point self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; self.window.backgroundColor = [UIColor cyanColor]; self.window.rootViewController = [[AppViewController alloc] init]; [self.window makeKeyAndVisible]; return YES; } @end 

所以让我们在[self.window makeKeyAndVisible]之后改变窗口的框架

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [UIWindow new]; self.window.backgroundColor = [UIColor cyanColor]; self.window.rootViewController = [[AppViewController alloc] init]; [self.window makeKeyAndVisible]; // Here it is self.window.frame = [UIScreen mainScreen].bounds; return YES; } 

我认为这是iOS 8的错误。

我有一个类似的问题,只有一个肖像的应用程序。

我通过在实例化UIWindow之前设置状态栏方向来解决问题

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Init my stuff // ... // Prepare window [application setStatusBarOrientation:UIInterfaceOrientationPortrait animated:NO]; // prevent start orientation bug self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; [self.window makeKeyAndVisible]; return YES; } 

在你的情况下,你应该在setStatusBarOrientation:animated:方法中使用setStatusBarOrientation:animated: (或Right)。

希望它可以帮助你。

就个人而言,上述解决scheme都没有工作。 我最后在我的主xib中为窗口设置了“隐藏”为YES,如下所示: _UIApplicationHandleEventFromQueueEvent,_windowServerHitTestWindow中意外的nil窗口

添加启动屏幕时,问题就解决了,只能通过向info.plist添加一个额外的属性来完成

自己有这个问题,我不知道如果你可以通过代码添加它,但我只能设法使其与info.plist +启动屏幕xib文件

 <key>UILaunchStoryboardName</key> <string>Launch Screen</string> 

其实我不认为你必须添加一个xib文件,如果只是关键(与任何值)是可用的plist它应该工作。

这里或其他地方发布的解决scheme都不适合我。

但是,我发现这个问题显然不是故事板发生的,所以另一种解决scheme是从xibs中移走。 (这个事实令人遗憾的是,苹果也不可能认真对待这个问题。)