web-dev-qa-db-ja.com

横向きを使用すると、UIWindowのサイズが正しくない

空のアプリケーションがあり、ストーリーボードもxibも関与していません。ステータスバーを非表示にし、横向きのみをサポートしたい。繰り返しますが、これらの変更はコード内でのみ行うのではなく、Info.plistには触れないでください。

問題

私は、サポートされている唯一の向きが横向きであると言うコントローラーでUIWindowを作成します。その場合、UIWindowは縦長モードの次元で作成され、回転しません。予想される結果は、完全にシアンの画面になります。

Broken 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];

まだいくつかの問題があります。最初はとても壊れやすいようで、私はこれが好きではありません。 2番目の問題は、GLKViewControllerをrootViewControllerとして設定するより複雑なアプリケーションで、次の結果が得られることです(左側に黒い領域がないことが予想されます)。

Broken GLKViewController

ステータスバーが十分に早く非表示になっていないようです。いくつかのジェスチャー認識機能がアクティブで、GLKViewControllerにあり、黒い領域をクリックすると、次のログメッセージが生成されます。

2014-09-25 13:20:42.170 StackOverflowExample [6971:107907] _UIApplicationHandleEventFromQueueEventの予期しないnilウィンドウ、_windowServerHitTestWindow:UIClassicWindow:0x7fa20b805e00;フレーム=(0 0; 375 667); userInteractionEnabled = NO; GestureRecognizers = NSArray:0x7fa20b80a620;レイヤー= UIWindowLayer:0x7fa20b806890

空のUIViewControllerをアタッチしたり、ビューをサブビューとして追加するなど、他のさまざまな変更も行いました。その場合、私のビューは正しく見えますが、ウィンドウはまだ間違った寸法を使用しています。

ビューコントローラーでsupportedInterfaceOrientationsメソッドをオーバーライドしないと、すべてが正しく回転します。しかし、それはもちろん私が望んでいることではありません。

17
Joa Ebert

landscapeアプリをportraitモードから実行すると、UIScreenにはiOS 8でportraitの境界があります(このアプリがアプリスイッチパネルにない場合のみ、 iOS 8がキャッシュを作成するため)。 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のバグだと思います。

25
LorikMalorik

私は似たような問題を抱えていました。

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;
}

あなたの場合、UIInterfaceOrienationLandscapeLeft(またはRight)をsetStatusBarOrientation:animated: 方法。

お役に立てば幸いです。

8
DrAL3X

個人的には、上記の解決策はどれもうまくいきませんでした。ここで最初に提案したように、メインのxibのウィンドウに対して「hidden」をYESに設定しました: _ UIApplicationHandleEventFromQueueEvent、_windowServerHitTestWindow の予期しないnilウィンドウ

2
onekiloparsec

UIWindowを回転させるには、1行だけ追加します。 UIWindowのrootControllerを設定できます。例えば:

fileprivate(set) var bottonOverlayWindow = UIWindow()

self.bottonOverlayWindow.rootViewController = self; 

// 'self'は、UIWindowビューを追加したViewControllerになります。したがって、ViewControllerが方向を変更すると、ウィンドウビューも方向を変更します。

問題が発生した場合はお知らせください。

1
Nishant Sharma

この問題は、起動画面を追加するときに解決されます。これは、info.plistに追加のプロパティを追加することによってのみ実行できます。

私自身もこの問題を抱えていましたが、コードで追加できるかどうかはわかりませんが、info.plist + Launch Screen xibファイルでのみ機能させることができました

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

実際には、xibファイルを追加する必要はないと思います。plistでキー(任意の値を含む)のみが使用可能な場合、それは機能するはずです。

0
Andy Jacobs

ここや他の場所に投稿された解決策はどれも私にとってうまくいきませんでした。

ただし、この問題はストーリーボードでは発生しないようです。そのため、別の解決策はxibsから移行することです。 (この事実は残念ながら、Appleが問題を真剣に受け止める可能性を低くします。)

0
mrueg