前提
iOS 7からView Controller単位でステータスバーを設定しやすいようになりました。
ベストプラクティス
Info.plist
はじめに、Info.plistでUIViewControllerBasedStatusBarAppearance
がNO
になっていないことを確認します。NO
だったらこれまでと同様
[UIApplication sharedApplication].statusBarStyle
で設定することになります。
アプリ起動時のDefaultイメージでは、Info.plistが優先されるので、Info.plistでUIStatusBarStyle
を設定しておきます。
UIViewController
ここからView Controllerでの設定についてみていきます。重要なのはUIViewController
のふたつのメソッドです。
preferredStatusBarStyle
ひとつめは
- (UIStatusBarStyle)preferredStatusBarStyle
で、これはそのView Controllerがどういうステータスバーが良いかを表現するためのメソッドです。適宜オーバーライドして、UIStatusBarStyleDefault
かUIStatusBarStyleLightContent
のどちらかを返します。
childViewControllerForStatusBarStyle
もうひとつは
- (UIViewController *)childViewControllerForStatusBarStyle
です。このメソッドでnil
を返すと、上で説明したpreferredStatusBarStyle
が使われます。なんらかのView Controllerを返したときは返したView Controllerの要求に従います。このメソッドはView Controllerのコンテナ的なView Controllerで使われます。例えばUITabBarController
ではこのメソッドが実装されていて、selectedViewController
が返っているように見えます。
コンテナ
ここからが問題で、UINavigationController
ではchildViewControllerForStatusBarStyle
がnil
を返しています。とはいえNavigation Controllerを使っていてステータスバーのスタイルを変えたいとき、UINavigationController
をサブクラスするのは感心しません。よりよいのは、UINavigationBar
の
@property(nonatomic, assign) UIBarStyle barStyle
を設定することです。UIBarStyle
にはUIBarStyleDefault
とUIBarStyleBlack
があります。これらが設定されたとき、UIStatusBarStyle
はそれぞれUIStatusBarStyleDefault
とUIStatusBarStyleLightContent
になります。
追記(2016/07/01)
追加情報です。UINavigationControllerでもナビゲーションバーが非表示の時はvisibleViewControllerに制御が委譲されるようです。 / “iOS 7におけるUIStatusBarStyleのベス…” https://t.co/YZAr6DAf2p
— Syo Ikeda / いけしょー (@ikesyo) 2016年7月1日
navigationBarHidden
が真のとき、visibleViewController
が childViewControllerForStatusBarStyle
になるそうです。Navigation Bar の色合いなどを反映する必要がないので、納得ですね。
あとUISplitViewController
のときはどうしたらいいのか分からなかった。サブクラスしてpreferredStatusBarStyle
をオーバーライドする以外になんかできるなら知りたいので皆さまの知見を募集いたします。
参考
Mastering iOS 7 UIStatusBarStyle (Example) | Coderwall
UIViewControllerBasedStatusBarAppearanceについての“正しい”情報がこちらにありました / “Max Howell : Mastering iOS 7 UIStatusBarStyle” http://t.co/qNq4ANHgcm
— Hiroki Kato (@cockscomb) November 12, 2013