201

Xcode 8.0 ベータ 4 を使用しています。

以前のバージョンでは、UIViewController にステータス バーのスタイルを設定するメソッドがありました。

public func preferredStatusBarStyle() -> UIStatusBarStyle

ただし、Swift 3 では「Get ONLY varaiable」に変更されていることがわかりました。

public var preferredStatusBarStyle: UIStatusBarStyle { get } 

UIViewController で使用するスタイルを提供するにはどうすればよいですか?

4

33 に答える 33

175

最新のアップデート (Xcode 10+ / Swift 4.2+)

この記事は、過去数年間存在していたさまざまなアプローチの背後にあるロジックを理解しようとする人のためにそのまま残されています。一方、Xcode 10 の時点で、Swift 4.2 の最初のアプローチは廃止され、サポートされなくなりました (つまり、それを使用しようとしても効果がありません)。Plist.infoフラグとカスタマイズの実践の背後にある理由をよりよく理解するための情報として引き続き参照されます。

重要な説明

ステータス バーの外観をカスタマイズする 2 つの方法を理解することは非常に重要です。それらは異なるものであり、混在させるべきではありません。

最初のアプローチ – アプリ全体で 1 つの色 (iOS7 以降は非推奨)

info.plist で、というキーを見つけるか作成します

View controller-based status bar appearance

NOに設定します。

それは何をしますか?これは基本的に、アプリケーションで、ステータス バーの外観が各ビュー コントローラーによって個別に定義されていないことを示す設定を確立します。これを理解することは非常に重要です。これは、アプリ全体、すべての画面で設定が統一されていることを意味します。2 つの設定があります。default白い背景に黒いテキストの 、またはlightContent黒い背景に白いテキストの です。

これらのいずれかを設定するには (すべての画面で 1 つの設定):

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    application.statusBarStyle = .lightContent // .default
    return true
}

これにより、各ビュー コントローラーでこの設定を再確立する必要がなくなります。ただし、いつでもこの方法に頼って、自発的に外観を変更できます。

2 番目のアプローチ – 各ビュー コントローラーの個別の色

これは反対です。機能させるには、info.plist に移動して設定します

View controller-based status bar appearance

はい

UIViewControllerこのように、必要な各インスタンスにこの実装を挿入すると、新しいView Controllerが開かれるたびに、ステータスバーのスタイルが個別に設定されます。

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent // .default
}

最初と同じように、ステータスバーの暗いスタイルまたは明るいスタイルを各View Controllerに個別に設定します。

このプロパティは、次の 2 つのシナリオで UIKit によって取得されます。

  1. 画面初期化時、UI準備時。
  2. setNeedsStatusBarAppearanceUpdate()コードを呼び出すと。

後者の場合、次のコードでステータスバーの外観を操作できます。

var isDark = false {
    didSet {
        setNeedsStatusBarAppearanceUpdate()
    }
}

override var preferredStatusBarStyle: UIStatusBarStyle {
    return isDark ? .lightContent : .default
}

func toggleAppearance() {
   isDark.toggle()
}

その後、 を呼び出すたびにtoggleAppearance()、ステータスバー スタイルの変更がトリガーされます。

3 番目のアプローチ – ハック!

ステータスバーに直接アクセスできるハックがあります:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    
    if let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView {
        statusBar.backgroundColor = UIColor.blue
    }
    
    return true
}

なぜハッキングするのですか?黒または白以外のステータス バーの色が必要な場合は、文書化されていない API を使用します。statusBarKVC を使用してオブジェクトを取得し、その背景色を設定します。この方法で得られるオブジェクトはUIStatusBarであり、これはから派生しUIViewているため、プロパティを自然にサポートしbackgroundColorます。UINavigationBarこれは汚い方法であり、合法的な方法ではありませんが、これまでのところ、ステータスバーのカスタムカラーを設定する唯一の方法です ( navbar + statusbar の外観を完全にカスタマイズできるアプローチを考慮していません)。アプリが拒否される可能性があります。しかし、あなたは幸運かもしれません。もしそうなら、特定の複雑な状況 (入れ子になった子ナビゲーションやビュー コントローラーの階層など) では、これがほとんど唯一の方法かもしれません。

Xcode 10+、Swift 4.2

もう代替手段はありません。開発者は、フラグをYESに設定して(または、デフォルトで YES であるため、このアクションを省略して)、上記の手順に従って、ビュー コントローラーにステータスバーの外観を定義させる必要があります。


ボーナス

任意の段階でステータスバーの外観を自発的に変更するために、複雑な状況で使用できるハックベースのソリューション (推奨されませんが)。色に関しては、次の拡張メソッドは、通常のアプローチで実行できることを正確に実行します。必要に応じて調整できます。

extension UIViewController {
    func setStatusBarStyle(_ style: UIStatusBarStyle) {
        if let statusBar = UIApplication.shared.value(forKey: "statusBar") as? UIView {
            statusBar.backgroundColor = style == .lightContent ? UIColor.black : .white
            statusBar.setValue(style == .lightContent ? UIColor.white : .black, forKey: "foregroundColor")
        }
    }
}
于 2017-12-11T10:13:26.477 に答える
132

返された値を設定するのではなく、オーバーライドすることができます。メソッドは { get } として宣言されているため、getter を提供するだけです。

 override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

これを条件付きで設定するsetNeedsStatusBarAppearanceUpdate()場合は、準備ができたときに変更をアニメーション化するように呼び出す必要があります

于 2016-08-03T10:52:21.347 に答える
109

Swift 3 & 4、iOS 10 & 11、Xcode 9 & 10
私にとって、この方法は機能しません:

override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
}

各View Controllerに慣れていたとき、これはうまくいきました:

  • ファイル info.list で、row:View controller-based status bar appearanceを追加し、次のように設定します。NO

  • 次の appdelegate:

    UIApplication.shared.statusBarStyle = .lightContent
    
于 2016-11-09T10:00:14.070 に答える
46

Xcode 10 以降

Swift 5でテスト済み

コードは必要ありません。以下の手順に従ってください。

アプリ全体のステータスバーを変更したい場合。

  1. Project Navigator (左側のパネル) から Project を選択します。
  2. ターゲットを選択します。
  3. 一般タブを選択します。
  4. 展開情報を見つけます。
  5. ステータス バーのスタイルをLightに変更します(暗い背景の場合は「Light」、明るい背景の場合は「Default」 ) 。

info.plist の変更を忘れないでください

  1. 情報タブを選択
  2. このキーを plist ファイルに追加します "コントローラーベースのステータスバーの外観を表示する" = NO

プロジェクトを実行して確認します。

Swift 5およびXcode 10.2および11.0の私のプロジェクト

于 2019-05-21T09:23:24.533 に答える
15

ストーリーボードでもこれを行うことができます

  1. info.plist に新しいエントリを作成し、「コントローラ ベースのステータス バーの外観を表示する」を「YES」に設定します。
  2. ストーリーボードに移動し、変更するナビゲーション コントローラーを選択します。ストーリーボード ドキュメント アウトライン セクション (ストーリーボードの左パネル) のナビゲーション バーをクリックします。
  3. 右側のパネルに移動し、属性セクションをクリックします
  4. ナビゲーション バー セクションの下に、スタイルが表示されます。ご希望のスタイルを選択してください(デフォルトは黒用で、黒は白用です)

これは、お持ちのナビゲーション コントローラーごとに行う必要があります。ただし、そのナビゲーション コントローラーの下にあるビューは、すべてのビューのステータス バーのスタイル/色を選択したものに変更します。結果をすぐに確認でき、すべてのビュー コントローラーに余分なコード行を追加する必要がないため、このオプションの方が優れていると思います。

ここに画像の説明を入力

(すべてSwiftプロジェクトでXcode 8.3.3で完了)

于 2017-07-12T09:53:30.363 に答える
9

スイフト5

https://stackoverflow.com/a/40066798/2082851でPRAVEEN の回答の詳細を追加するには、実装を提供したいと思います。各コントローラのステータス バーを柔軟にカスタマイズできます。

全体として、すべてのケースでプロパティBaseViewControllerを処理する を作成します。statusBarStyle新しいコントローラを作成するときは、このベース コントローラのサブクラスとして作成します。

ステータスの外観を変更したいときはいつでも、このプロパティを更新するだけで済みます。ステータス バーのスタイルはすぐに更新されます。

実装

class BaseViewController: UIViewController {

    var statusBarStyle: UIStatusBarStyle = .default {
        didSet {
            setNeedsStatusBarAppearanceUpdate()
        }
    }

    override var preferredStatusBarStyle: UIStatusBarStyle {
        return statusBarStyle
    }
}

デモ

class ViewController: BaseViewController, UIScrollViewDelegate {

    let scrollView = UIScrollView()
    ... 
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        UIView.animate(withDuration: 0.3) {
            if scrollView.contentOffset.y > 30 {
                self.statusBarStyle = .darkContent
            } else {
                self.statusBarStyle = .lightContent
            }
        }
    }
}

ここに画像の説明を入力

2.UINavigationController

の場合UINavigationController、これは特殊なケースであり、次のいずれかのソリューションに従うことができます。

解決策 A: メッセージ ディスパッチでオーバーライドする

UINavigationController は であり、NSObjectから継承されてObjectiveCいるため、そのメソッドはmessage dispatchであり、オーバーライドできます。

extension UINavigationController {
   open override var preferredStatusBarStyle: UIStatusBarStyle {
      return topViewController?.preferredStatusBarStyle ?? .default
   }
}

解決策 B:UINavigationControllerサブクラスを作成する

カスタムUINavigationController(通常はより多くの要件を制御する必要がある) が既にある場合は、これが最適なソリューションです。

final class NavigationController: UINavigationController {
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return topViewController?.preferredStatusBarStyle ?? super.preferredStatusBarStyle
    }
}
于 2020-03-13T02:56:38.130 に答える
6

Xcode 8.3.1、スウィフト 3.1

  1. info.plist に新しいエントリを作成し、「コントローラ ベースのステータス バーの外観を表示する」を「NO」に設定します。

  2. AppDelegate.swift を開き、「didFinishLaunchingWithOptions」メソッドに次の行を追加します。

application.statusBarStyle = .lightContent

于 2017-04-22T14:16:15.820 に答える
5

Swift 4.0 "didFinishLaunchingWithOptions launchOptions:" Appdelegate クラスでこのコードを使用してください

UIApplication.shared.statusBarStyle = .lightContent
let statusBar: UIView = UIApplication.shared.value(forKey: "statusBar") as! UIView
if statusBar.responds(to: #selector(setter: UIView.backgroundColor)){
  statusBar.backgroundColor = UIColor.black
}
于 2017-11-03T03:12:05.123 に答える
2

これらの回答のほとんどは再ハッシュ化されたものと同じですが、暗い背景を使用している場合、実際に起動画面に対処するものはありません.

私はこれを次のように回避しました。これによりinfo.plist、明るいスタイルのステータスバーが生成されました。

<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
于 2018-08-13T06:57:05.337 に答える