プログラムでiOSステータスバーの高さを取得する方法


277

現在、iPhone / iPadの上部にあるステータスバー(時間、バッテリー、ネットワーク接続を含む)は、非網膜画面の場合は20ピクセル、網膜画面の場合は40ピクセルであることを知っていますが、将来の保証のために私のアプリが欲しいハードコーディング値なしでこれを決定できるようにするため。プログラムでステータスバーの高さを把握することは可能ですか?

回答:


506

[UIApplication sharedApplication].statusBarFrame.size.height。ただし、すべてのサイズはピクセル単位ではなくポイント単位であるため、ステータスバーの高さは常に20になります。

更新。この回答が役に立ったと思われるので、詳しく説明します。

ステータスバーの高さは、実際には20.0fポイントです。 次の場合を除いて

  • ステータスバーはsetStatusBarHidden:withAnimation:メソッドで非表示にされており、その高さは0.0fポイントです。
  • ここで@Antonが指摘したように、電話アプリケーションの外部での着信中または録音セッション中のステータスバーの高さは40.0fポイントです。

ビューの高さに影響を与えるステータスバーのケースもあります。通常、ビューの高さは、特定の向きのスクリーンの寸法からステータスバーの高さを引いたものに等しくなります。ただし、ビューが表示された後にステータスバーをアニメーション化(表示または非表示)すると、ステータスバーはフレームを変更しますが、ビュー変更されません。ん。ステータスバーのアニメーション後(またはアニメーション以降)、ビューのサイズを手動で変更する必要があります。ステータスバーの高さはアニメーションの開始時に最終値に設定されます)。

アップデート2。ユーザーインターフェース指向のケースもあります。ステータスバーは向きの値を考慮しないため、[UIApplication sharedApplication].statusBarFrame.size.height向きモードのステータスバーの高さの値は(はい、デフォルトの向きは、アプリのinfo.plistの内容に関係なく、常に縦向きです)、横向き - [UIApplication sharedApplication].statusBarFrame.size.widthです。UIの現在の向きを決定する際に外のUIViewControllerself.interfaceOrientation使用できない、使用[UIApplication sharedApplication].statusBarOrientation

iOS7のアップデート。ステータスバーの表示スタイルが変わっても、ステータスバーは表示されますが、フレームの動作は変わりません。私が得たステータスバーに関する唯一の興味深い発見–私は共有します:あなたUINavigationBarののタイル張りの背景もステータスバーに並べて表示されるため、興味深いデザイン効果を実現したり、ステータスバーに色を付けることができます。これも、ステータスバーの高さに影響を与えることはありません。

ナビゲーションバーのタイル背景がステータスバーにもタイル表示されます


6
このメソッドは1024(iOS7)を生成します
Marc

1
@MarcMosby、私の更新を参照してください。この問題を思い出しました-ありがとうございます。
Kyr Dunenkoff 2013

2
はい、MarcがiOS7で指摘したように、1024と20の場合もあります。したがって、これは高さを決定するためのばかげた方法ではありません。これは、iOS 7のステータスバーの透過的な性質によるものではないかと思います。それは、最初に全画面表示になり、次に自分自身のサイズを変更することです。したがって、この移行中にアプリクエリを実行すると、誤った値が取得される可能性があります。iOSの7の遅延かもしれないの助けを借りて、このメソッドを呼び出すことが可能
ディーパックGM

1
ステータスバーの高さがゼロになる場合があります。supportedInterfaceOrientations()がUIInterfaceOrientationMaskの代わりにUIInterfaceOrientation(誤った結果ですが、コンパイラエラーはありません)を返し、viewcontrollerが表示されて閉じられると、ステータスバーの高さがゼロになります。
Cymric 2015

5
また、iPhone Xではステータスバーが高くなります。
事前

98

一緒に行くの質問にマーティンの提案:iPhoneのステータスバーの高さを取得します

CGFloat AACStatusBarHeight()
{
    CGSize statusBarSize = [[UIApplication sharedApplication] statusBarFrame].size;
    return MIN(statusBarSize.width, statusBarSize.height);
}

そしてスウィフトでは

func statusBarHeight() -> CGFloat {
    let statusBarSize = UIApplication.shared.statusBarFrame.size
    return Swift.min(statusBarSize.width, statusBarSize.height)
}

ハックのように見えますが、実際にはかなりしっかりしています。とにかく、それが唯一の実用的なソリューションです。

古い答え

次のコードは、 UIViewControllerランドスケープをサポートするためにほぼ機能しました。しかし、コーナーケース(右から回転した場合>サポートされていない上下逆>左)が機能しない(高さと幅が切り替わる)ことに気付きました。

BOOL isPortrait = self.interfaceOrientation == UIInterfaceOrientationPortrait;
CGSize statusBarSize = [UIApplication sharedApplication].statusBarFrame.size;
CGFloat statusBarHeight = (isPortrait ? statusBarSize.height : statusBarSize.width);

これは正しくありません。デバイスを回転させても、ステータスバーの高さは変わりません。幅はありますが、上のコードはそれを示していませんし、元の質問もそうではありませんでした。
lehn0058 2013年

1
「デバイスを回転させてもステータスバーの高さは変わらない」というのはあなたの言う通りです。しかし、Ashが答えたように、「横長モードでは、幅と高さが入れ替わることがあります。」上記のコードはそれを考慮に入れています。
ma11hew28 2013年

これは私が今も見ている興味深い問題です。私にはApple側のバグのように見えますが、それでも説明する必要があります。
lehn0058 2014年

2
@ lehn0058これはバグではなく、Appleが内部でバーを処理する方法です。これはウィンドウにアタッチされ、そのウィンドウは変換を使用して回転されます。statusBarFrame変換前の値として返されます。
レオナタン14年

1
それはプロパティとしてより良く見えます:Dvar statusBarHeight: CGFloat
Pablo A.

23

これを試して:

CGFloat statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;

1
異なる方向で返される高さは異なります。それは奇妙です
tGilani 2013

1
はい、回転が横向きの場合-[[UIApplication sharedApplication] statusBarFrame] .size.heightと[[UIApplication sharedApplication] statusBarFrame] .size.widthの値が入れ替わります。
Guntis Treulands、2014年


10

ステータスバーの高さは通常20ポイントですが、状況によってはその2倍になる場合があります。

  • あなたが電話の最中にいるとき(それはかなり一般的なシナリオです)。
  • ボイスレコーダー、Skype、または同様のアプリがバックグラウンドでマイクを使用しているとき。
  • パーソナルホットスポットがアクティブ化されたとき。

試してみてください。高さを20ptにハードコーディングしても、機能しないまでは機能します。

だから私はH2CO3の答えを2番目に:

statusBarHeight = [[UIApplication sharedApplication] statusBarFrame].size.height;

10

編集 ビューコンテンツの上部に配置する場所を決めるiOS 11の方法は、UIViewのsafeAreaLayoutGuideUIViewドキュメントを参照です。

非推奨ANSWER あなたはiOSの7+をターゲットに設定している場合、のUIViewControllerのドキュメントはのViewControllerのことをアドバイスしtopLayoutGuide、それはまた、目に見えるかどうプロパティは、あなたのステータスバーの下、またはナビゲーションバーの下を与えます。これは役に立つかもしれず、確かに以前の多くのソリューションよりもハックが少ないです。


5

ステータスバーのフレームが画面の座標空間にあることを忘れないでください!横モードで起動すると、幅と高さが入れ替わることがあります。横向きをサポートする場合は、代わりにこのバージョンのコードを使用することを強くお勧めします。

CGRect statusBarFrame = [self.window convertRect:[UIApplication sharedApplication].statusBarFrame toView:view];

その後、statusBarFrameのheightプロパティを直接読み取ることができます。このインスタンスの「ビュー」は、測定値を使用するビューである必要があります。おそらく、アプリケーションウィンドウのルートビューコントローラーです。

ちなみに、ステータスバーは、通話中により高くなるだけでなく、意図的に非表示にされている場合はゼロになることもあります。


これは私に正しい高さを与えませんでした。しかし、私は私のために働く別の方法を見つけました:stackoverflow.com/a/16598350/242933
ma11hew28

ええ、これは今ではかなり古いコードなので、おそらく有効な答えではありません。個人的には、自動レイアウトのおかげで、ステータスバーの高さを確認する必要がなくなりました。
Ash



1
    var statusHeight: CGFloat!
    if #available(iOS 13.0, *) {
         statusHeight = UIApplication.shared.keyWindow?.windowScene?.statusBarManager?.statusBarFrame.height
    } else {
        // Fallback on earlier versions
        statusHeight = UIApplication.shared.statusBarFrame.height
    }


0

ステータスバーの高さに直接アクセスするのではなく、計算する方法を見つけました。

ナビゲーションバーの高さ-topLayoutGuideの長さ=ステータスバーの高さ

迅速:

let statusBarHeight = self.topLayoutGuide.length-self.navigationController?.navigationBar.frame.height

self.topLayoutGuide.length半透明のバーで覆われている上部の領域でself.navigationController?.navigationBar.frame.heightあり、ステータスバーを除く半透明のバーです。通常は44ptです。したがって、この方法を使用すると、電話によるステータスバーの高さの変化を気にすることなく、ステータスバーの高さを簡単に計算できます。


これは機能せず、self.topLayoutGuide.length0なので結果は-44になります。
ナンバティー2017年

@nambatee私はiOS 11なので、もう動作しないと思いますAppleはsafeAreaInsetsを使用しています
Henry Ngan


-6

次の1行のコードを使用すると、ステータスバーの高さを任意の方向で取得できます。

#define STATUS_BAR_HIGHT (
    [UIApplicationsharedApplication].statusBarHidden ? 0 : (
        [UIApplicationsharedApplication].statusBarFrame.size.height > 100 ?
            [UIApplicationsharedApplication].statusBarFrame.size.width :
            [UIApplicationsharedApplication].statusBarFrame.size.height
    )
)

シンプルですが非常に便利なマクロです。追加のコードを記述する必要はありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.