web-dev-qa-db-ja.com

UIStatusBarStyle PreferredStatusBarStyleはiOS 7では機能しません

IOS 7向けXcode 5で構築されたiPhoneアプリケーションでは、UIViewControllerBasedStatusBarAppearance=YESinfo.plistを設定し、ViewControllerには次のコードがあります。

-(UIStatusBarStyle) preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

しかし、ステータスバーは黒の背景に対して黒のままです。

UIViewControllerBasedStatusBarAppearance=NOinfo.plistを設定することでこのアプリ全体を変更できることはわかっていますが、実際には、実行時にviewControllerごとにviewControllerごとに変更する必要があります。

107
Andrew Smith

OK、ここにトリックがあります。キー「View Controller-based status bar」を追加し、値をNoに設定する必要があります。

これは、このキーの意味が表示されるものに反しますが、値をNoに設定しても、ステータスバーの外観と、View Controllerで表示するかどうかを変更できます。したがって、「はい」のように機能しますが、「いいえ」に設定します。

これで、ステータスバーを白または暗くすることができます。

86
Andrew Smith

ViewControllerがnavigationController内にある場合、navigationControllerのnavigationBar.barStyleがstatusBarStyleを決定することを発見しました。

NavigationBarのbarStyleUIBarStyleBlackTranslucentに設定すると、白いステータスバーテキスト(つまりUIStatusBarStyleLightContent)が設定され、UIBarStyleDefaultが黒いステータスバーテキスト(つまりUIStatusBarStyleDefault )。

これは、barTintColorを介してnavigationBarの色を完全に変更しても適用されます。

278
mxcl

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
    }

}
72
Daniel Wood

私はこれに少し遅れて来るかもしれませんが、他の誰かが実用的で検証されたアプリ全体のソリューションを探している場合に備えて。

@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を取得します。それ以外の場合は、デフォルトを返します。

これが必要な人に役立つことを願っています。

33
Kyle Begeman

受け入れられた回答の詳細を提供するには、アプリのデリゲートの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

21
Matthew Quiros

ViewDidLoadでこれを書いてください

[self setNeedsStatusBarAppearanceUpdate];

ちょうどそれを行うと、それは動作します

これを試してください

Set UIViewControllerBasedStatusBarAppearance to NO.
Call [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

あなたがこのような方法を書いたというあなたの質問で私が見たもう一つのこと

 -(void)UIStatusBarStyle PreferredStatusBarStyle ()
        {
            return UIStatusBarStyle.LightContent;
        }

でもこんな感じ

-(UIStatusBarStyle)preferredStatusBarStyle{ 
    return UIStatusBarStyleLightContent; 
} 
10
User 1531343

ここに私がそれを解決した方法があります。通常、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
    }
}
5
aryaxt

ここにすべての答えがあっても、私はまだ正確な解決策を見つけられませんでしたが、ダニエルからの答えから始めました。私が終わったのは:

override var preferredStatusBarStyle: UIStatusBarStyle {
     return visibleViewController?.preferredStatusBarStyle ?? .lightContent
}

ナビゲーションコントローラー(タブと同様、selectedViewControllerのみ)。そして、それは尊重します:

override var preferredStatusBarStyle: UIStatusBarStyle {
     return .lightContent
}

特に設定しない限り、各View Controllerで。どこでもsetNeedsStatusBarAppearanceUpdate()を呼び出す必要はありません。各View Controllerに到着すると更新されます。

4
Andrew Plummer

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;
}
3
Fatih Aksu

Swift 4.2

extension UITabBarController {
    open override var childForStatusBarStyle: UIViewController? {
        return selectedViewController
    }
}

extension UINavigationController {
    open override var childForStatusBarStyle: UIViewController? {
        return visibleViewController
    }
}
2
Vyacheslav

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;
}
1
onmyway133

迅速な例

appDelegate.Swiftで

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
    UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent;

    return true
}

info.plistセットでコントローラーベースのステータスバーの外観を表示:いいえ

1
fyalavuz

SplashScreen中にstatusBarを非表示にしたいが、スタイルをライトコンテンツに変更したい場合(PlistのStatusBarInitiallyHiddenはNOにして、splashのstatusBarを非表示にする必要があります)、これをappDelegateのdidFinishLaunchingWithOptionsメソッドに追加してlightContentに変更できます。

[[UIApplication sharedApplication]setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
[[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent];
1
aalesano

ステータスバーのスタイルを設定できます。 IOS 6以下のようなステータスバーに似ています。
View Controllerにこのメソッドを貼り付けます

-(UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleBlackOpaque;
}

ビューからこのメソッドを呼び出すと、このようにロードされました

if([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f)
    {
       [self setNeedsStatusBarAppearanceUpdate];
    }
0
Ganapathy

私が直面した特定のケースにメモを追加したいだけです。アプリに別のUIWindowを使用して、チャットフェイスを常にアプリ全体に表示するようにしました。これを行うと、上記の解決策のどれも機能しなくなり、なぜそうなるのか本当に分かりません!私が気づいたのは、新しいUIWindowのViewControllerがその理由だということです!ステータスバーのスタイルを変更したい場合は、新しいUIWindowのビューコントローラーで変更する必要があります。

このメモは、同様の構造を持つ他の人を助けるかもしれません!したがって、基本的に、新しいUIWindowのViewControllerで上記のソリューションを適用できます。

これも特定のケースです。

ありがとう

0
Ehab Saifan