Xcode 11.4。Navigationのタイトルカラーがストーリーボードから黒くなりました


55

最近、Xcodeを11.4に更新しました。デバイスでアプリを実行すると、ストーリーボードから設定されていると、すべてのナビゲーションアイテムのタイトルが完全に黒くなっていることに気付きました。 ここに画像の説明を入力してください

コードから変更することはできません。次のコード行は機能しなくなります

self.navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white]

私はそれをいくつかのiOS 13のものを使用してのみ動作させるUINavigationBarAppearance

@available(iOS 13.0, *)
    private func setupNavigationBar() {
        let app = UINavigationBarAppearance()
        app.titleTextAttributes = [.foregroundColor: UIColor.white]
        app.backgroundColor = Constants.Color.barColor
        self.navigationController?.navigationBar.compactAppearance = app
        self.navigationController?.navigationBar.standardAppearance = app
        self.navigationController?.navigationBar.scrollEdgeAppearance = app

        self.navigationController?.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white]
    }

誰かがなぜ私に説明できますか??? これは重大なバグですか、それとも新しい隠し機能ですか?


3
ここで同じ問題があり、これを修正するために何もすることが見つかりません。バグだと思います:/
ジョーダンファブレイ

林檎。うーん。本当に?
ダニエル


Xcodeインターフェースビルダーです。バグの更新XCodeを11.4.1に
NinjaDeveloper

回答:



36

これにより、代わりにUINavigationBarAppearanceを使用してそれを修正しました:アプリのナビゲーションバーのカスタマイズ

if #available(iOS 13.0, *) {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithOpaqueBackground()
    appearance.backgroundColor = UIColor.black
    appearance.titleTextAttributes = [.foregroundColor: UIColor.white] // With a red background, make the title more readable.
    self.navigationBar.standardAppearance = appearance
    self.navigationBar.scrollEdgeAppearance = appearance
    self.navigationBar.compactAppearance = appearance // For iPhone small navigation bar in landscape.
} else {
    self.navigationBar.barTintColor = UIColor.black
    self.navigationBar.tintColor = UIColor.white
    self.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.white]
}

注:私はUINavigationControllerをサブクラス化し、これはviewWillAppearのオーバーライドから呼び出されました。

...またはAppDelegateの場合、アプリ全体:

if #available(iOS 13.0, *) {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithOpaqueBackground()
    appearance.backgroundColor = UIColor.black
    appearance.titleTextAttributes = [
        NSAttributedStringKey.foregroundColor: UIColor.white
    ]

    let buttonAppearance = UIBarButtonItemAppearance()
    buttonAppearance.normal.titleTextAttributes = [.foregroundColor: UIColor.white]
    appearance.buttonAppearance = buttonAppearance

    UINavigationBar.appearance().standardAppearance = appearance
    UINavigationBar.appearance().scrollEdgeAppearance = appearance
    UINavigationBar.appearance().compactAppearance = appearance

    UIBarButtonItem.appearance().tintColor = UIColor.white
} else {
    UINavigationBar.appearance().barTintColor = UIColor.black
    UINavigationBar.appearance().titleTextAttributes = [
        NSAttributedStringKey.foregroundColor: UIColor.white
    ]
    UINavigationBar.appearance().tintColor = UIColor.white

    UIBarButtonItem.appearance().tintColor = UIColor.white
}

... AppDelegate、アプリ全体、Objective-Cの場合:

if (@available(iOS 13, *)) {
    UINavigationBarAppearance *appearance = [[UINavigationBarAppearance alloc] init];
    [appearance configureWithOpaqueBackground];
    appearance.backgroundColor = UIColor.whiteColor;
    appearance.titleTextAttributes = titleAttributes;

    UIBarButtonItemAppearance *buttonAppearance = [[UIBarButtonItemAppearance alloc] init];
    buttonAppearance.normal.titleTextAttributes = barButtonItemAttributes;
    appearance.buttonAppearance = buttonAppearance;

    UINavigationBar.appearance.standardAppearance = appearance;
    UINavigationBar.appearance.scrollEdgeAppearance = appearance;
    UINavigationBar.appearance.compactAppearance = appearance;

    [[UINavigationBar appearance] setTintColor:UIColor.blackColor];
} else {
    [[UINavigationBar appearance] setBarTintColor:UIColor.whiteColor];
    [[UINavigationBar appearance] setTintColor:UIColor.blackColor];
    [[UINavigationBar appearance] setTranslucent:false];
    [[UINavigationBar appearance] setTitleTextAttributes: titleAttributes];
    [[UIBarButtonItem appearance] setTitleTextAttributes:barButtonItemAttributes forState:UIControlStateNormal];
}

ありがとう、これは正解です!、iOS 13ではAppleが追加さUINavigationBarAppearance()れ、理由もなく古いXcodeに依存する必要はありませんでしたが、Xcode 11.4以降は使用する必要があります。そうしないとUINavigationBarAppearance()、タイトルの色は常に黒になります。
バジル

appearance.largeTitleTextAttributes大きなタイトルの場合。
スコア

これはうまくいき、ありがとう!、とにかくこれをAppDelegateから普遍的に行う方法はありますか?
スライサー

@slicerdicer-うん!例については、私の最新の回答を参照してください。乾杯。
Stu Carney

1
@Richard-Objective-Cの回答を追加しました。今日までコメントがありませんでした。
Stu Carney

14

ストーリーボードで、ナビゲーションコントローラーの「バーティント」を「デフォルト」値に変更し、コードで通常のように変更できます。


3
ベストアンサー。本当に。
Vladimir Prigarin

2
これが正しい方法です
Hugo

1
最高の回答期間❗️。
シャドウシープ

2
@ JCutting8うん、そうだね。ただし、Xcode 11.4では、ストーリーボードでデフォルトの色を設定しないと、プログラムで変更しても機能しません。これが問題であるかどうかはわかりません。
シャドウシープ

1
これは魔法です!
ekashking

6

それがバグかどうかわからない。

修正方法は、プロジェクト設定で「ステータスバースタイル」を暗いまたは明るいコンテンツに設定することです。これにより、ステータスバーのテキストの色が、ライトモードまたはダークモードのデバイスに基づいて決定されるのではなく、特定の方法で強制されます。

さらに、Info.plistで値「View controller-based status bar appear」を「NO」に設定する必要があります。その値がない場合、「ステータスバーのスタイル」は上書きされます。

次に、カスタムナビゲーションコントローラーを作成し、ストーリーボードに実装します。

class CustomNavigationController: UINavigationController {

 override func viewDidLoad() {
    super.viewDidLoad()
    setNavBar()
 }

 func setNavBar() {
    if #available(iOS 13.0, *) {
        let appearance = UINavigationBarAppearance()
        appearance.configureWithOpaqueBackground()
        appearance.backgroundColor = UIColor.blue
        appearance.titleTextAttributes = [.foregroundColor: UIColor.yellow]
        self.navigationBar.standardAppearance = appearance
        self.navigationBar.scrollEdgeAppearance = appearance
        self.navigationBar.compactAppearance = appearance
    } else {
        self.navigationBar.barTintColor = UIColor.blue
        self.navigationBar.titleTextAttributes = [.foregroundColor: UIColor.yellow]
    }
  }
}

*色が設定されているので、はっきりと見えます。

色を最初のロードで設定しておらず、ナビゲートしてリロードした後で初めて、ViewDidAppearではなくViewDidLoadでコードを設定した方がよいことがわかりました。

また、この問題はNavBarの「バーティント」に関連している可能性があることもわかりました。最初に解決しようとしたときに、「バーティント」をデフォルトに設定すると、エラーも解決されたようです。ただし、NavBarの背景色を希望どおりに取得できなかったためです。したがって、ストーリーボードでは、適切な測定のために、この値をデフォルトに設定しました。

それが役に立てば幸い


これは機能します。うまくいかないグローバルスタイルを設定しているだけのようです。
Mongo

アップル側のバグを防ごう。>。<
マイケルマッケンナ

2

Xcode Interface Builderのバグである回避策は必要ありません。Xcode 11.4.1のAppleリリースアップデート

Apple開発者リリースノートから

インターフェースビルダー

Xcode 11.4でビルドするときにストーリーボードとXIBドキュメントで設定された一部のUINavigationBarの外観プロパティが無視される問題を修正しました。(60883063)(FB7639654)

https://developer.apple.com/documentation/xcode_release_notes/xcode_11_4_1_release_notes


0

3/25のStu Carneyの応答と同様に、実装の詳細をさらにいくつか追加しました。

UINavigationControllerのサブクラスを作成します。以下をviewWillAppearに追加します。

let isDarkMode = UserDefaults.standard.bool(forKey: "DarkMode")
let titleColor: UIColor = isDarkMode ? .white : .black
let navBarColor: UIColor = isDarkMode ? .black : .white
let tintColor: UIColor = isDarkMode ? .yellow : .red  //back button text and arrow color, as well as right bar button item

if #available(iOS 13.0, *) {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithOpaqueBackground()
    appearance.backgroundColor = navBarColor
    appearance.titleTextAttributes = [.foregroundColor: titleColor]
    appearance.largeTitleTextAttributes = [.foregroundColor: titleColor]

    self.navigationBar.standardAppearance = appearance
    self.navigationBar.scrollEdgeAppearance = appearance
    self.navigationBar.compactAppearance = appearance // For iPhone small navigation bar in landscape.

    self.navigationBar.tintColor = tintColor //changes back button text and arrow color, as well as right bar button item
} else {
    self.navigationBar.barTintColor = navBarColor
    self.navigationBar.tintColor = tintColor
    self.navigationBar.titleTextAttributes = [.foregroundColor: titleColor]
    self.navigationBar.largeTitleTextAttributes = [.foregroundColor: titleColor]
}

次に、preferredStatusBarStyleをオーバーライドします。

override var preferredStatusBarStyle: UIStatusBarStyle {
    let isDarkMode = UserDefaults.standard.bool(forKey: "DarkMode")
    return isDarkMode ? .lightContent : .default
}

UISwitch IBActionやセレクターメソッドからなど、ナビゲーションバーとステータスバーを動的に更新する場合は、以下を追加します。

navigationController?.loadView()
navigationController?.topViewController?.setNeedsStatusBarAppearanceUpdate()

また、すべてのナビゲーションバーとバーボタンをIBのデフォルトの色に設定してください。Xcodeには、IBの色がプログラムで設定された色を上書きするというバグがあるようです。


0

私の場合、Xcodeを11.3から11.4にアップグレードした後、このバグが発生しました。そのため、ナビゲーションバーで画像を背景として設定するには、コードを変更してブローする必要があります。

if #available(iOS 13.0, *) {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithOpaqueBackground()
    let backgroundImage = UIImage(named: "{NAVBAR_IMAGE_NAME}")?.resizableImage(withCapInsets: UIEdgeInsets.zero, resizingMode: .stretch)
    appearance.backgroundImage = backgroundImage
    self.navigationController?.navigationBar.compactAppearance = appearance
    self.navigationController?.navigationBar.standardAppearance = appearance
    self.navigationController?.navigationBar.scrollEdgeAppearance = appearance        
} else {
    self.navigationController?.navigationBar.barTintColor = Utils.themeColor
    let backgroundImage = UIImage(named: "{NAVBAR_IMAGE_NAME}")?.resizableImage(withCapInsets: UIEdgeInsets.zero, resizingMode: .stretch)
    self.navigationController?.navigationBar.setBackgroundImage(backgroundImage, for: .default)
    self.navigationController?.navigationBar.shadowImage = UIImage()
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.