前提
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
