概要
最近のバージョンの iOS を搭載した iPhone の Landscape モードでステータスバーを表示させる方法がないか、いろいろと試してみたのですが、どうやらそのような方法はないようです。(方法が見つかりませんでした。)
確認環境
ビルド環境
- macOS 10.15.5
- Xcode 11.5 (11E608c)
- Deployment Target: iOS 11.0
- User Interface が Storyboard の Xcode プロジェクトを使用
実行環境
- iPhone 11 Pro Max (iOS 13.5.1)
- iOS Simulator (iPhone Xs Max, iOS 12.4)
- iOS Simulator (iPad Air 2, iOS 12.4)
試したこと
prefersStatusBarHidden
が false
を返すようにする
ステータスバーを表示させたい画面の View Controller で UIViewController
クラスのプロパティ prefersStatusBarHidden
1 をオーバーライドして false
を返すようにします。つまり、常にステータスバーを表示するように設定するのです。
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
override var prefersStatusBarHidden: Bool {
return false
}
}
Info.plist
で View controller-based status bar appearance
の値に YES
を設定
prefersStatusBarHidden
をオーバーライドしただけでは、対象の画面を表示した時や画面回転時に prefersStatusBarHidden
の値が参照されません。
次の画像のように、 Xcode で対象のビルドターゲットについての Info.plist
の内容を表示し、その中で View controller-based status bar appearance
の項目の値に YES
を設定します。これにより、上述の prefersStatusBarHidden
の値が使用されるようになります。
なお、View controller-based status bar appearance
という項目は、 Info.plist
のソースコードでは UIViewControllerBasedStatusBarAppearance
2 というキーで表されます。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- 省略 -->
<key>UIViewControllerBasedStatusBarAppearance</key>
<true/>
</dict>
</plist>
なるべくシンプルな画面構成で動作確認
UINavigationController
や UITabBarController
などの Container View Controller を使う場合、 childForStatusBarHidden
を適切に設定しなければなりません。今回は prefersStatusBarHidden
の値の使い方を中心に確認したいため、 こうした Container View Controller は使用せずに、なるべくシンプルな画面構成で動作確認することにしました。
Xcodeの新規プロジェクト作成メニューから Single View App
テンプレートを選択して Xcode プロジェクトを作成し、そのプロジェクト内の ViewController
クラスに変更を加えることにより動作確認しました。
確認結果
上記の設定を試してみたのですが、 iPhone では画面表示時や画面回転時に prefersStatusBarHidden
が呼び出されるものの、 Landscape モードのときにはステータスバーが表示されません。( iPad では常に、また、iPhone が Portrait モードのときには、ステータスバーが表示されます。)
Developer Documentation の記述から判断できること
あらためて prefersStatusBarHidden
についての Developer Documentation1 の Discussion を確認してみたところ、次のように書かれていました。
By default, this method returns false with one exception. For apps linked against iOS 8 or later, this method returns true if the view controller is in a vertically compact environment.
この記述によると、 prefersStatusBarHidden
が返す値には以下の規則性があるということです。
- デフォルトでは
false
を返す。 - iOS 8 以降にリンクされたアプリでは View Controller の Size Class の横幅が
Compact
の場合にはtrue
を返す。
また、 Human Interface Guidelines に記載されている各デバイスの Size Class の一覧表を見ると、 iPhone の全機種の Size Class の横幅が Compact
であることがわかります。
実際に動作確認してみた結果と照らし合わせてみると、オーバーライドした prefersStatusBarHidden
が常に false
を返すようになっていたとしても、その View Controller のSize Class の横幅が Compact
の場合には、 true
を返しているものとして iOS の内部では評価されているようです。