IOS 7向けXcode 5で構築されたiPhoneアプリケーションでは、UIViewControllerBasedStatusBarAppearance=YES
にinfo.plist
を設定し、ViewController
には次のコードがあります。
-(UIStatusBarStyle) preferredStatusBarStyle
{
return UIStatusBarStyleLightContent;
}
しかし、ステータスバーは黒の背景に対して黒のままです。
UIViewControllerBasedStatusBarAppearance=NO
でinfo.plist
を設定することでこのアプリ全体を変更できることはわかっていますが、実際には、実行時にviewController
ごとにviewController
ごとに変更する必要があります。
OK、ここにトリックがあります。キー「View Controller-based status bar」を追加し、値をNoに設定する必要があります。
これは、このキーの意味が表示されるものに反しますが、値をNo
に設定しても、ステータスバーの外観と、View Controllerで表示するかどうかを変更できます。したがって、「はい」のように機能しますが、「いいえ」に設定します。
これで、ステータスバーを白または暗くすることができます。
ViewControllerがnavigationController内にある場合、navigationControllerのnavigationBar.barStyle
がstatusBarStyleを決定することを発見しました。
NavigationBarのbarStyle
をUIBarStyleBlackTranslucent
に設定すると、白いステータスバーテキスト(つまりUIStatusBarStyleLightContent
)が設定され、UIBarStyleDefault
が黒いステータスバーテキスト(つまりUIStatusBarStyleDefault
)。
注これは、barTintColor
を介してnavigationBarの色を完全に変更しても適用されます。
preferredStatusBarStyle()
がUINavigationController
およびUITabBarController
内で機能するように、現在表示されているView Controllerから優先ステータスバースタイルを取得する次のコードを追加します。
extension UITabBarController {
public override func childViewControllerForStatusBarStyle() -> UIViewController? {
return selectedViewController
}
}
extension UINavigationController {
public override func childViewControllerForStatusBarStyle() -> UIViewController? {
return visibleViewController
}
}
Swiftの場合、これらはメソッドではなくプロパティです。
extension UITabBarController {
open override var childViewControllerForStatusBarStyle: UIViewController? {
return selectedViewController
}
}
extension UINavigationController {
open override var childViewControllerForStatusBarStyle: UIViewController? {
return visibleViewController
}
}
Swift 4.2プロパティの名前が変更されました:
extension UITabBarController {
open override var childForStatusBarStyle: UIViewController? {
return selectedViewController
}
}
extension UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
return visibleViewController
}
}
使用法
class ViewController: UIViewController {
// This will be called every time the ViewController appears
// Works great for pushing & popping
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
私はこれに少し遅れて来るかもしれませんが、他の誰かが実用的で検証されたアプリ全体のソリューションを探している場合に備えて。
@mxclは、これが起こっている理由を説明するのに正しいです。これを修正するには、UINavigationControllerのpreferredSatusBarStyle()メソッドをオーバーライドする拡張機能(またはobj-cのカテゴリ)を作成するだけです。 Swiftの例を次に示します。
extension UINavigationController {
public override func preferredStatusBarStyle() -> UIStatusBarStyle {
if let rootViewController = self.viewControllers.first {
return rootViewController.preferredStatusBarStyle()
}
return super.preferredStatusBarStyle()
}
}
このコードは、最初のView Controller(ルートView Controller)を抽出して展開するだけです(obj-cでは、nilでないことを確認してください)。展開が成功した場合(nilではない)、rootViewControllers preferredStatusBarStyleを取得します。それ以外の場合は、デフォルトを返します。
これが必要な人に役立つことを願っています。
受け入れられた回答の詳細を提供するには、アプリのデリゲートのdidFinishLaunchingWithOptions:
メソッドに次の行を追加します。
[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
次に、Info.plistでView controller-based status bar appearance
を追加し、NO
に設定します。
アプリ全体で同じステータスバーの色が必要な場合、Navigation Controllerからではなく、それがそれを行うべき方法だと思います。 UINavigationController
、または別の場所にある別のUINavigationController
サブクラスなどに必ずしも埋め込まれていない画面があるかもしれません。
EDIT:コードを入力せずに行うこともできます: https://stackoverflow.com/a/18732865/85568
ViewDidLoadでこれを書いてください
[self setNeedsStatusBarAppearanceUpdate];
ちょうどそれを行うと、それは動作します
これを試してください
Set UIViewControllerBasedStatusBarAppearance to NO.
Call [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
あなたがこのような方法を書いたというあなたの質問で私が見たもう一つのこと
-(void)UIStatusBarStyle PreferredStatusBarStyle ()
{
return UIStatusBarStyle.LightContent;
}
でもこんな感じ
-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}
ここに私がそれを解決した方法があります。通常、navigationControllerまたはtabBarControllerは、ステータスバーの外観(非表示、色など)を決定するものです。
そのため、私はNavigation Controllerをサブクラス化し、preferredStatusBarStyleをオーバーライドしました。現在表示されているViewContorllerがStatusBarStyleHandlerを実装している場合、スタイルとして使用する値を要求します。そうでない場合は、デフォルト値を返します。
ステータスバーの外観の更新をトリガーするには、setNeedsStatusBarAppearanceUpdate
を再度呼び出して、preferredStatusBarStyle
を再度トリガーし、メソッドが返す内容に従ってUIを更新します。
public protocol StatusBarStyleHandler {
var preferredStatusBarStyle: UIStatusBarStyle { get }
}
public class CustomNavigationCotnroller: UINavigationController {
public override var preferredStatusBarStyle: UIStatusBarStyle {
if let statusBarHandler = visibleViewController as? StatusBarStyleHandler {
return statusBarHandler.preferredStatusBarStyle
}
return .default
}
}
次に使用方法
public class SomeController: UIViewController, StatusBarStyleHandler {
private var statusBarToggle = true
// just a sample for toggling the status bar style each time method is called
private func toggleStatusBarColor() {
statusBarToggle = !statusBarToggle
setNeedsStatusBarAppearanceUpdate()
}
public override var preferredStatusBarStyle: UIStatusBarStyle {
return statusBarToggle ? .lightContent : .default
}
}
ここにすべての答えがあっても、私はまだ正確な解決策を見つけられませんでしたが、ダニエルからの答えから始めました。私が終わったのは:
override var preferredStatusBarStyle: UIStatusBarStyle {
return visibleViewController?.preferredStatusBarStyle ?? .lightContent
}
ナビゲーションコントローラー(タブと同様、selectedViewControllerのみ)。そして、それは尊重します:
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
特に設定しない限り、各View Controllerで。どこでもsetNeedsStatusBarAppearanceUpdate()
を呼び出す必要はありません。各View Controllerに到着すると更新されます。
1)プロジェクト全体の1つの設定:
可能な場合は、info.plistからUIViewControllerBasedStatusBarAppearance
キーと値のペアを削除するか、削除せずにNO
を設定します。 info.plistで利用できない場合は、何もしません。このプロパティのデフォルトはNO
です。
以下のコードをAppDelegate.mに追加します。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}
2)View Controllerごとに異なる設定:
Info.plistにUIViewControllerBasedStatusBarAppearance
キーと値のペアを追加し、YES
に設定します。
View ControllerがNavigation Controllerに組み込まれていない場合。 MyViewControllerとしましょう。以下のコードをMyViewController.mファイルに追加するだけです。 View ControllerがNavigation Controllerに組み込まれている場合は、新しいCocoa Touchクラスを作成し、UINavigationControllerのサブクラスにします。 MyNCとしましょう。ストーリーボードの右側のペインで[ナビゲーションコントローラービュー]を選択します。 [ユーティリティ]-> [IDインスペクター]-> [カスタムクラス]-> [クラス]に「MyNC」と入力します。 Storyboard Viewを「MyNC」Cocoa Touchクラスにリンクした後、以下のコードをMyNC.mに追加します。
- (BOOL)prefersStatusBarHidden {
return NO;
}
-(UIStatusBarStyle)preferredStatusBarStyle {
return UIStatusBarStyleLightContent;
}
Swift 4.2
extension UITabBarController {
open override var childForStatusBarStyle: UIViewController? {
return selectedViewController
}
}
extension UINavigationController {
open override var childForStatusBarStyle: UIViewController? {
return visibleViewController
}
}
NavigationController
を使用している場合は、NavigationController
をサブクラス化して、子View Controllerに問い合わせることができます
// MyCustomNavigationController
- (NSUInteger)supportedInterfaceOrientations {
UIViewController *viewControllerToAsk = [self findChildVC];
return [viewControllerToAsk supportedInterfaceOrientations];
}
- (BOOL)shouldAutorotate {
UIViewController *viewControllerToAsk = [self findChildVC];
return [viewControllerToAsk shouldAutorotate];
}
- (UIStatusBarStyle)preferredStatusBarStyle {
UIViewController *viewControllerToAsk = [self findChildVC];
return [viewControllerToAsk preferredStatusBarStyle];
}
- (UIViewController *)findChildVC {
return self.viewControllers.firstObject;
}
迅速な例
appDelegate.Swiftで
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent;
return true
}
info.plistセットでコントローラーベースのステータスバーの外観を表示:いいえ
SplashScreen中にstatusBarを非表示にしたいが、スタイルをライトコンテンツに変更したい場合(PlistのStatusBarInitiallyHiddenはNOにして、splashのstatusBarを非表示にする必要があります)、これをappDelegateのdidFinishLaunchingWithOptionsメソッドに追加してlightContentに変更できます。
[[UIApplication sharedApplication]setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
[[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent];
ステータスバーのスタイルを設定できます。 IOS 6以下のようなステータスバーに似ています。
View Controllerにこのメソッドを貼り付けます
-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleBlackOpaque;
}
ビューからこのメソッドを呼び出すと、このようにロードされました
if([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f)
{
[self setNeedsStatusBarAppearanceUpdate];
}
私が直面した特定のケースにメモを追加したいだけです。アプリに別のUIWindowを使用して、チャットフェイスを常にアプリ全体に表示するようにしました。これを行うと、上記の解決策のどれも機能しなくなり、なぜそうなるのか本当に分かりません!私が気づいたのは、新しいUIWindowのViewControllerがその理由だということです!ステータスバーのスタイルを変更したい場合は、新しいUIWindowのビューコントローラーで変更する必要があります。
このメモは、同様の構造を持つ他の人を助けるかもしれません!したがって、基本的に、新しいUIWindowのViewControllerで上記のソリューションを適用できます。
これも特定のケースです。
ありがとう