【SwiftUI】iOS 16.1でUINavigationBar.appearance().tintColorの設定が反映されなくなっていることに気付いて対応した
iOS 16.1のシミュレータでアプリを触っていると、UINavigationBar.appearance().tintColor
で設定しているはずのNavigationBarの戻るボタンの色がデフォルトの色になっていることに気付いたので対応しました。
環境
- Xcode 14.1
コード
import SwiftUI struct ContentView: View { init() { setupNavigationBarTintColor() } var body: some View { NavigationView { NavigationLink("Next") { NextView() .navigationBarTitleDisplayMode(.inline) } } } private func setupNavigationBarTintColor() { // NavigationBarのtintColorを黒に変更 UINavigationBar.appearance().tintColor = .black } } /// 次の画面 struct NextView: View { var body: some View { Rectangle() .fill(.mint) .overlay { Text("Next") } } }
プレビュー
iOS 15.5
iOS 16.1
iOS 15.5では反映されていたUINavigationBar.appearance().tintColor
が、iOS 16.1では反映されなくなっています。(今回検証で使用していたのはiOS 16.1ですが、iOS 16から同じ現象になっています)
対応策
その1. 色を変更したUIImageを設定
やや力技になりますが、色を変更したUIImage
をUINavigationBar.appearance().backIndicatorImage
に設定して、タイトルの色の変更はUIBarButtonItem.appearance().setTitleTextAttributes
を使用して変更する方法です。
上記、検証コードで紹介したsetupNavigationBarTintColor
メソッドの内容を下記に変更します。
private func setupNavigationBarTintColor() { // 黒色のChevronLeftImageを作成 let blackChevronLeftImage = UIImage(systemName: "chevron.backward")!.withTintColor(.black, renderingMode: .alwaysOriginal) // 黒に設定したUIImageをbackIndicatorImageに渡す UINavigationBar.appearance().backIndicatorImage = blackChevronLeftImage UINavigationBar.appearance().backIndicatorTransitionMaskImage = blackChevronLeftImage // UIBarButtonItemのタイトルテキストのforegroundColorを黒に設定 UIBarButtonItem.appearance().setTitleTextAttributes([.foregroundColor: UIColor.black], for: .normal) }
これでNavigationBarの戻るボタンの色をiOS 16.1でも意図していた色に変更することが出来ました。
その2. NavigationViewに.tintを設定
対策案1では、少し力技で変更したのですが、こちらはNavigationView
に.tint
を使用するだけのシンプルな方法になります。
import SwiftUI struct ContentView: View { var body: some View { NavigationView { NavigationLink("Next") { NextView() .navigationBarTitleDisplayMode(.inline) } } .tint(.black) } } /// 次の画面 struct NextView: View { var body: some View { Rectangle() .fill(.mint) .overlay { Text("Next") } } }
.tint(_:)
を使用することで、Viewのデフォルトのアクセントカラーをオーバーライドすることが出来ます。.tint(_:)
はiOS 15以上の利用となっていますが、現在非推奨となっているiOS 13.0以上で使用できるaccentColor(_:)
でもアクセントカラーを設定でき、同じように意図した色の反映が確認出来ました。
おわりに
iOS 16から使用できるNavigationStack
を使用する場合でも、同じようにUINavigationBar.appearance().tintColor
の変更では戻るボタンの色には反映されず、.tint(_:)
を使用して変更できることを確認しました。
まだまだ動きの定まらないSwiftUIのNavigationですが、広い心で受け止めてあげたいと思います。これからもよろしくお願いします。
この記事が誰かの助けになればと思います。