1. ホーム
  2. ios

[解決済み] 画面の向きに依存した高さと幅を取得するには?

2023-01-24 09:37:55

質問

私は自分のアプリケーションの現在の高さと幅をプログラムによって決定しようとしています。私はこれを使用しています。

CGRect screenRect = [[UIScreen mainScreen] bounds];

しかし、これでは、デバイスが縦向きか横向きかに関係なく、幅が320、高さが480になります。どうすれば 現在の の幅と高さ (つまり、デバイスの向きに依存) を決定するにはどうしたらよいでしょうか?

どのように解決するのですか?

次のようなものを使うことができます。 UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation) を使用して向きを決定し、それに応じて寸法を使用します。

しかし、UIViewController のような方向転換の際に

- (void) willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation 
                                 duration:(NSTimeInterval)duration

で渡された向きを toInterfaceOrientation の中にいるので、UIApplicationのstatusBarOrientationはまだ変更されていないので、古い方向を指すことになります( will イベントハンドラ内なので)。

概要

これにはいくつかの関連記事がありますが、いずれも「そうしなければならない」ということを示しているようです。

  1. を見てください。 [[UIScreen mainScreen] bounds] を見て、寸法を求めます。
  2. どのような向きになっているかを確認し
  3. ステータス バーの高さ (表示されている場合) を考慮します。

リンク

動作コード

私は通常、ここまでしませんが、あなたは私の興味をそそりました。 次のコードは、トリックを行う必要があります。 私は UIApplication の Category を書きました。 currentSizeまたは指定された方向でのサイズを取得するクラスメソッドを追加しました。これは、UIViewControllerの willRotateToInterfaceOrientation:duration: .

@interface UIApplication (AppDimensions)
+(CGSize) currentSize;
+(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation;
@end

@implementation UIApplication (AppDimensions)

+(CGSize) currentSize
{
    return [UIApplication sizeInOrientation:[UIApplication sharedApplication].statusBarOrientation];
}

+(CGSize) sizeInOrientation:(UIInterfaceOrientation)orientation
{
    CGSize size = [UIScreen mainScreen].bounds.size;
    UIApplication *application = [UIApplication sharedApplication];
    if (UIInterfaceOrientationIsLandscape(orientation))
    {
        size = CGSizeMake(size.height, size.width);
    }
    if (application.statusBarHidden == NO)
    {
        size.height -= MIN(application.statusBarFrame.size.width, application.statusBarFrame.size.height);
    }
    return size;
}

@end

このコードを使うには、単純に [UIApplication currentSize] . また、上記のコードを実行してみたところ、すべての方向で正しい応答が返されることが確認できました。 ステータスバーを考慮に入れていることに注意してください。 興味深いことに、私はステータス バーの高さと幅の MIN を差し引かなければなりませんでした。

これが役立つことを願っています。 :D

その他の考え

寸法を取得するために、UIWindowの rootViewController プロパティを見ることで寸法を得ることができます。 私は過去にこれを調べましたが、rotate トランスフォームを持つことを報告する以外は、縦方向と横方向の両方で同じ寸法を同様に報告しました。

(gdb) po [[[UIApplication sharedApplication]] keyWindow] ]。 rootViewController] ビュー] です。

<UILayoutContainerView: 0xf7296f0; frame = (0 0; 320 480); transform = [0, -1, 1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0xf729b80>>

(gdb) po [[[UIApplication sharedApplication] keyWindow] rootViewController] view] です。

<UILayoutContainerView: 0xf7296f0; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0xf729b80>>

あなたのアプリがどのように動作するかわかりませんが、何らかのナビゲーションコントローラを使用していない場合、メインビューの下に親の最大高さ/幅を持つUIViewを持つことができ、親と共に成長/縮小することができます。 そうすれば、こうなります。 [[[[[[[UIApplication sharedApplication] keyWindow] rootViewController] view] subviews] objectAtIndex:0] frame] . これは1行でかなり強烈に見えますが、アイデアを得ることができます。

しかし...。 やはり上記3つのステップを概要の下で行うのがベターでしょう。 UIAlertViewを表示すると、UIApplicationのkeywindowがUIAlertViewが作成した新しいUIWindowを指すように変更されるなど、UIWindowsをいじり始めると、奇妙なことに気がつくでしょう。 誰が知っている? keyWindowに依存するバグを見つけた後、そのように変更されることを発見したのです!