使用横向时UIWindow的大小错误

Joa*_*ert 17 iphone landscape objective-c uiwindow ios

我有一个空的应用程序,没有涉及故事板或xib.我希望有一个隐藏的状态栏,只支持横向.同样,我不想仅在代码中进行这些更改,也不要触摸Info.plist.

问题

我创建了一个带控制器的UIWindow,它表示唯一支持的方向是landscape.在这种情况下,我的UIWindow是在纵向模式的维度中创建的,不会旋转.预期结果将是完全青色的屏幕.

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
Run Code Online (Sandbox Code Playgroud)

这是我的控制器:

#import "AppViewController.h"

@implementation AppViewController

- (BOOL)shouldAutorotate {
  return YES;
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
  return UIInterfaceOrientationLandscapeLeft;
}

- (BOOL)prefersStatusBarHidden {
  return YES;
}

- (NSUInteger)supportedInterfaceOrientations {
  return UIInterfaceOrientationMaskLandscape;
}

@end
Run Code Online (Sandbox Code Playgroud)

到目前为止我尝试过的

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

self.window.backgroundColor = [UIColor cyanColor];
[self.window makeKeyAndVisible];
self.window.rootViewController = [[AppViewController alloc] init];
Run Code Online (Sandbox Code Playgroud)

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

破碎的GLKViewController

看起来状态栏没有及早隐藏.几个手势识别器处于活动状态,在GLKViewController中单击黑色区域会产生以下日志消息:

2014-09-25 13:20:42.170 StackOverflowExample [6971:107907] _UIApplicationHandleEventFromQueueEvent中的意外nil窗口,_ windowowServerHitTestWindow:UIClassicWindow:0x7fa20b805e00; frame =(0 0; 375 667); userInteractionEnabled = NO; gestureRecognizers = NSArray:0x7fa20b80a620; layer = UIWindowLayer:0x7fa20b806890

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

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

Lor*_*rik 25

当您从纵向模式运行横向应用程序时,UIScreen 在iOS 8中具有纵向边界(仅当您在应用程序切换面板中没有此应用程序时,因为iOS 8会进行一些缓存).即使显示窗口也不会改变它的框架.但它根据可用的方向而改变.makeKeyAndVisible[UIScreen mainScreen].boundsAppViewController

#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
Run Code Online (Sandbox Code Playgroud)

那么让我们改变窗口的框架 [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;
}
Run Code Online (Sandbox Code Playgroud)

我认为这是iOS 8的bug.


DrA*_*L3X 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;
}
Run Code Online (Sandbox Code Playgroud)

在您的情况下,您应该UIInterfaceOrienationLandscapeLeftsetStatusBarOrientation:animated:方法中使用(或右).

希望它能帮到你.