web-dev-qa-db-ja.com

iOS13では、ステータスバーの背景色は、ラージテキストモードのナビゲーションバーとは異なります

Problems demo

問題を再現するための前提条件:

  1. Xcode 11ベータ+ iOS 13(2019年6月12日までの最新バージョン)
  2. ナビゲーションバーは大きいテキストモードです
  3. ナビゲーションバーの色を指定します。

ステータスバーは、実際のデバイスでは緑色のナビゲーションバーの上にある白いままです。

私が試したソリューション:

  1. IOS12に戻すと解決しますが、最終的にはiOS13に遭遇します...
  2. 大きなテキストモードを無効にすると解決します...
  3. ステータスバーを非表示にすると修正されますが、ステータステキストがナビゲーションバーアイテムと重なってしまいます。

何か案は?どんな助けにも感謝します。

47
steven

ここではハックやファンキーさは必要ありません。重要なのは、目的の外観を定義し、ナビゲーションバーのstandardAppearanceとそのscrollEdgeAppearanceの両方にこの値を設定することです。アプリ全体のベースナビゲーションコントローラーサブクラスのinitに次のコードがあります。

if #available(iOS 13.0, *) {
    let navBarAppearance = UINavigationBarAppearance()
    navBarAppearance.configureWithOpaqueBackground()
    navBarAppearance.titleTextAttributes = [.foregroundColor: UIColor.white]
    navBarAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
    navBarAppearance.backgroundColor = <insert your color here>
    navigationBar.standardAppearance = navBarAppearance
    navigationBar.scrollEdgeAppearance = navBarAppearance
}

enter image description here

123
Mike

IOS 13では、大きなタイトルを使用するナビゲーションバーの透明色はAppleヒューマンインターフェイスガイドラインです。詳細はこちら こちら

IOS 13以降では、デフォルトで大きなタイトルナビゲーションバーに背景素材や影が含まれていません。また、ユーザーがコンテンツをスクロールし始めると、大きなタイトルは標準のタイトルに移行します

12
Hans Knöchel

大きなタイトルが表示されているときにナビゲーションバーに色を付けたいという問題がある場合は、新しいUINavigationBarAppearanceクラスを使用します。

    let app = UINavigationBarAppearance()
    app.backgroundColor = .blue
    self.navigationController?.navigationBar.scrollEdgeAppearance = app
9
matt

ユニバーサルコード

        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.backgroundColor = // your color
        navBarAppearance.shadowImage = nil // line
        navBarAppearance.shadowColor = nil // line
        UINavigationBar.appearance(whenContainedInInstancesOf: [UINavigationController.self]).standardAppearance = navBarAppearance
        UINavigationBar.appearance(whenContainedInInstancesOf: [UINavigationController.self]).scrollEdgeAppearance = navBarAppearance
6

私のnavigationBar拡張、iOS 13 Swift 5

extension UIViewController {
func configureNavigationBar(largeTitleColor: UIColor, backgoundColor: UIColor, tintColor: UIColor, title: String, preferredLargeTitle: Bool) {
    if #available(iOS 13.0, *) {
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.largeTitleTextAttributes = [.foregroundColor: largeTitleColor]
        navBarAppearance.titleTextAttributes = [.foregroundColor: largeTitleColor]
        navBarAppearance.backgroundColor = backgoundColor

        navigationController?.navigationBar.standardAppearance = navBarAppearance
        navigationController?.navigationBar.compactAppearance = navBarAppearance
        navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance

        navigationController?.navigationBar.prefersLargeTitles = preferredLargeTitle
        navigationController?.navigationBar.isTranslucent = false
        navigationController?.navigationBar.tintColor = tintColor
        navigationItem.title = title

    } else {
        // Fallback on earlier versions
        navigationController?.navigationBar.barTintColor = backgoundColor
        navigationController?.navigationBar.tintColor = tintColor
        navigationController?.navigationBar.isTranslucent = false
        navigationItem.title = title
    }
}}

使い方:

configureNavigationBar(largeTitleColor: .yourColor, backgoundColor: .yourColor, tintColor: .yourColor, title: "YourTitle", preferredLargeTitle: true)

軽いコンテンツが必要な場合は、info.plistでViewControllerベースのステータスバーをNOに設定します。

LargeTitlesが不要な場合はfalseに設定します

IOS 13でテストされています。

6
Fabio

Objective CソリューションとiOS 13

UINavigationBarAppearance* navBarAppearance = [self.navigationController.navigationBar standardAppearance];
        [navBarAppearance configureWithOpaqueBackground];
        navBarAppearance.titleTextAttributes = @{NSForegroundColorAttributeName:TitleColor};
        navBarAppearance.largeTitleTextAttributes = @{NSForegroundColorAttributeName: TitleColor};
        navBarAppearance.backgroundColor = TopColor;
        self.navigationController.navigationBar.standardAppearance = navBarAppearance;
        self.navigationController.navigationBar.scrollEdgeAppearance = navBarAppearance;
5
mohammad alabid

IOS 13の場合、バーの影の線が表示されるという問題がありました。バーの影の画像をnilに設定すると、この問題は解決しました。

func configureNavigation() {
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.myColor,
                                                     .font: UIFont(name: "MyFont", size: 42)!]
        navBarAppearance.backgroundColor = .white
        navigationController?.navigationBar.isTranslucent = false
        navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
    }

Image with shadow

func configureNavigation() {
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.myColor,
                                                     .font: UIFont(name: "MyFont", size: 42)!]
        navBarAppearance.backgroundColor = .white
        navBarAppearance.shadowColor = nil
        navigationController?.navigationBar.isTranslucent = false
        navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
    }

Image without shadow

3
Andrew Edwards

マイクとハンスの答えに感謝します。私のケースは半透明のステータスバーとアルファ0.5のナビゲーションバーです。 iOS13は複雑に見えます。以下は私のテスト結果ですが、両方を透過的にしたい場合に機能します。

if #available(iOS 13.0, *) {
                let navBarAppearance = UINavigationBarAppearance()
                // This only set top status bar as transparent, not the nav bar.
                navBarAppearance .configureWithTransparentBackground()
                // This set the color for both status bar and nav bar(alpha 1).
                navBarAppearance.backgroundColor = UIColor.red.withAlphaComponent(0.5)
                navigationController?.navigationBar.standardAppearance = navBarAppearance
                navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
                // Nav bar need sets to translucent for both nav bar and status bar to be translucent.
                navigationController?.navigationBar.isTranslucent = true
                // // Need to reset nav bar's color to make it clear to display navBarAppearance's color
                navigationController?.navigationBar.backgroundColor = UIColor.clear
               } 
1
Ning

IOS 13との互換性を高めるためにアプリの1つを更新すると、同様の問題が発生しました。上記の Hans と同様に、大きなタイトルはデフォルトで透明になります。私のようにストーリーボードのヘビーユーザーである場合は、サイドバーに簡単にオンにできる別の設定があります。

ストーリーボードのナビゲーションバーをクリックすると、通常はデフォルトでNavigation Itemが選択され、カスタマイズオプションは表示されません。上の[Navigation Bar]オプションを選択すると、右側のインスペクタで、必要なもののカスタム背景色を選択できます。

enter image description here

1
Drew

Swift 5

override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
    super.traitCollectionDidChange(previousTraitCollection)

    let userInterfaceStyle = traitCollection.userInterfaceStyle
    modeDetect(userInterfaceStyle: userInterfaceStyle)

}

override func viewDidAppear(_ animated: Bool) {
    navigationController?.navigationBar.barStyle = .black
    navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white]
}

func modeDetect(userInterfaceStyle: UIUserInterfaceStyle) {
    switch userInterfaceStyle {
    case .light:
        navigationController?.navigationBar.barTintColor = .systemPink
    case .dark:
        navigationController?.navigationBar.barTintColor = .systemBackground
    default:
        break
    }
}
0
Dumex

適切な引数を指定してこの関数を呼び出します。このコードは正しく機能しています。

open func showNavigationBar(large: Bool,
                            animated: Bool,
                            isTransparabar: Bool,
                            titleColor: UIColor,
                            barBackGroundColor: UIColor,
                            fontSize: CGFloat) {

        navigationController?.navigationBar.barTintColor = barBackGroundColor
        navigationController?.navigationBar.backgroundColor = barBackGroundColor
        navigationController?.navigationBar.isTranslucent = true
        self.navigationController?.setNavigationBarHidden(false, animated: animated)
        if large {
            self.navigationController?.navigationBar.prefersLargeTitles = true
            if #available(iOS 13.0, *) {
                let appearance = UINavigationBarAppearance()
                appearance.backgroundColor = barBackGroundColor
                appearance.titleTextAttributes = [.foregroundColor: titleColor]
                appearance.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: titleColor]

                navigationController?.navigationBar.standardAppearance = appearance
                navigationController?.navigationBar.compactAppearance = appearance
                navigationController?.navigationBar.scrollEdgeAppearance = appearance
            } else {
                self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedString.Key.foregroundColor: titleColor]
            }
        } else {
            self.navigationController?.navigationBar.prefersLargeTitles = false
            self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: titleColor!]
        }
    }
0
Kiran Sarvaiya

次のObjective-Cコードにより、iOS 13ナビゲーションバーは以前のバージョンと同じように動作しました。

    if (@available(iOS 13.0, *)) {
        // Setup iOS 13 navigation bar
        sharedSelector.navigationBar.scrollEdgeAppearance = sharedSelector.navigationBar.standardAppearance;
    } else {
        // Fallback on earlier versions
    }
0
André Pinto

ストーリーボードでは、ナビゲーションバーを偽造する必要があることを発見しました(緑色が不透明であると仮定すると、実際には不透明なナビゲーションバーでのみ機能します)。私が見つけた最良の方法は、安全領域のインセットに合うプレースホルダービュー(紫)を作成し、残りの高さであるナビゲーションバー(シアン/青)の後ろに偽のビューを追加することでした。私のプロジェクトでは機能しますが、ええ、それは少しハックです。 Screenshot from Xcode 11 beta 4 displaying constraints required for status bar hack

編集:これは主に、カスタムのビューコントローラークラスを使用できないLaunchScreen.storyboard用です。

0
SunburstEnzo