Xamarin.iOSでステータスバーの高さを取得する

提供: MonoBook
ナビゲーションに移動 検索に移動

iOSiPadOSで画面サイズを取得すると「ステータスバーまで含んだ大きさ」を返してくる。 このため何も考えずにプログラムで動的にビューを配置するとステータスバーにめり込む(重なる)ため、「ステータスバーの高さ」を取得して「まともなフルサイズ」を自前で計算する必要がある。

var screenSize = this.View.Frame;

var statusBarHeight = (なんらかの手法でステタスバの高さを取得する);

var fullSize = new CGRect(
    screenSize.X, 
    screenSize.Y + statusBarHeight,
    screenSize.Width,
    screenSize.Height - statusBarHeight);

iOS 12まで[編集 | ソースを編集]

iOS 12まではUIApplicationからステータスバーの高さを取得できた。

var h12 = UIApplication.SharedApplication?.StatusBarFrame.Height ?? 0;

iOS 13から[編集 | ソースを編集]

iOS 13からはUIWindowのStatusBarManager経由でステータスバーの高さを取得するように仕様変更された。

var h13 = this.View?.Window?.WindowScene?.StatusBarManager?.StatusBarFrame.Height ?? 0;

なお、前述のiOS 12までの古い方法をiOS 13で使うと「ゼロ」が返ってくる。このためしばらくアップデートされずに放置されているアプリはステータスバーにビューが重なっている。

UIWindowが有効になるタイミング[編集 | ソースを編集]

なお、UIViewControllerにおいてUIWindowが取得できるようになるのは「ViewDidAppear以降」となっているので注意すること。 ViewDidLoadやViewWillAppearの段階ではWindowプロパティは「null」となっている。

public partial class ViewController : UIViewController
{
    public nfloat StatusBarHeight => this.View?.Window?.WindowScene?.StatusBarManager?.StatusBarFrame.Height ?? 0;

    public override void ViewDidLoad()
    {
        base.ViewDidLoad();
        // まだ「0」
        Console.WriteLine($"ViewDidLoad={StatusBarHeight}");
    }
    public override void ViewWillAppear(bool animated)
    {
        base.ViewWillAppear(animated);
        // まだ「0」
        Console.WriteLine($"ViewWillAppear={StatusBarHeight}");
    }

    public override void ViewDidAppear(bool animated)
    {
        base.ViewDidAppear(animated);
        // ここで高さが取れる。
        Console.WriteLine($"ViewDidAppear={StatusBarHeight}");
    }
}