web-dev-qa-db-ja.com

ランドスケープアプリケーションの起動時にUIScreenapplicationFrameが誤った長方形を返す(iPhone / iPad)

ランドスケープモードで起動したときにiPadアプリケーションの正しい境界を取得するのに問題があります。 Info.plistファイルに適切なキーが設定されており、View Controllerが横向き(および縦向き、ナッチ)で正しく起動します。

私のapplicationDidFinishLaunching:メソッドでは、3秒の遅延後にセレクターを呼び出しており、そのメソッドは[[UIScreen mainScreen] applicationFrame]を呼び出していますが、ポートレートフレーム(つまり、高さ>幅)が返されます。

誰かがこれを修正する方法を知っていますか?それは私にはバグのようなにおいがします(もしそうなら私はレーダーを提出します)、しかしそれが意図された行動であるならば、それはどこに文書化されていますか?

21
jbrennan

IPadを横向きに持ってアプリを起動すると、View Controllerは最初に縦向きビューの境界を確認します(向きが横向きを報告している場合でも)。ビューコントローラは、表示される前に横向きに回転するメッセージを受け取ります。

6
progrmr

特にアプリの起動中は、[[UIScreen mainScreen] applicationFrame]に依存することはありません。

コードでビューを作成するときは、スーパービューを使用してフレームを設定します。

「シミュレートされたインターフェイス要素」でxibsを使用している場合、それらは正しいサイズになり、すべてがうまく機能します。

INavigationControllerベースのアプリ

UINavigationControllerベースのアプリの場合は、self.navigationController.viewから直接フレームを取得し、[self loadView]self.view.superviewを使用しないでください。 UINavigationControllerは、「非表示」サブビューを使用してそのジョブを実行します。そのため、直接スーパービューは機能しません。

UINavigationControllerは、アプリの起動時にloadViewが呼び出された後、ナビゲーションコントローラーがビューのサイズを変更するため特別です。自動サイズ変更が開始されると、画面の下部に小さな余白ができてしまいます。

なぜUIScreenではないのか

[[UIScreen mainScreen] applicationFrame]は確実に機能しません(特にランドスケープでのアプリの起動中)。私の経験では、ビューコントローラーのinterfaceOrientationプロパティはapplicationFrameの向きと一致しません。

35
bentford
CGRect bounds = [[UIScreen mainScreen] bounds]; // portrait bounds
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) {
    bounds.size = CGSizeMake(bounds.size.height, bounds.size.width);
}
14
100grams

これは、ViewControllerがランドスケープ上にあるときに正しいCGRectを取得する方法です。

CGRect landscapeBounds;
if (self.view.frame.size.width < self.view.frame.size.height)
    landscapeBounds = CGRectMake(self.view.frame.Origin.y, self.view.frame.Origin.x, self.view.frame.size.height, self.view.frame.size.width);
else
    landscapeBounds = CGRectMake(self.view.frame.Origin.x, self.view.frame.Origin.y, self.view.frame.size.width, self.view.frame.size.height);
6

これは設計どおりです。スーパービューのサイズを照会し、必要に応じて調整する必要があります。

5
rpetrich

[[UIScreen mainScreen] applicationFrame]は、アプリが横向きモードの場合でも、常に縦向きの長方形を返します。これは、UIWindowneverが実際に回転するという事実に関連していますが、代わりにrootViewController.viewの変換を変更するだけです。

念のため、ルートビューオブジェクトを縦向きモードと横向きモードで印刷すると、次のように表示されます。

肖像画:

<UIView: 0x96290e0; frame = (0 20; 768 1004); ...

風景:

<UIView: 0x96290e0; frame = (0 20; 768 1004); transform = [0, 1, -1, 0, 0, 0]; ...
2
Hejazi

したがって、Appleのガイドによると、起動イメージを追加し、それに接尾辞-568hを付けます。

健全な心を持っている人がなぜシステム設定をグラフィックに依存させるのか理解できません。しかし、私はテストしたばかりで、うまくいきました。

クイック検索の後で教えてくれた場所です 上記の回答は表示されませんでした。誰かに役立つと思いました。

S

1
Stephen J

CordovaプラグインでdismissViewControllerAnimatedを使用してビューを閉じるときに、同じ問題が発生しました。 MainViewControllerのviewWillAppearメソッドのsingingAtomコードを変更しました。これは、モーダルビューを閉じた後にサイズ変更されました。

- (void)viewWillAppear:(BOOL)animated
    {
    CGRect appFrame = [[UIScreen mainScreen] applicationFrame];
    UIDeviceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
    if (UIDeviceOrientationLandscapeLeft == orientation || 
        UIDeviceOrientationLandscapeRight == orientation)
            {
            if (appFrame.size.width < appFrame.size.height)
                {
                appFrame = CGRectMake(appFrame.Origin.y, appFrame.Origin.x, appFrame.size.height, appFrame.size.width);
                }
        }
    self.view.frame = appFrame;
    [super viewWillAppear:animated];
}
0
lietus