この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
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ですが、広い心で受け止めてあげたいと思います。これからもよろしくお願いします。
この記事が誰かの助けになればと思います。