SwiftUIでNavigationBarのBackgroundColorなどを変更する方法


やりたいこと

SwiftUIでNavigationBarの背景色を変える
UIAppearanceは使いたくない(強い意志)

結論

  • UINavigationBar.appearance()を使わずにNavigationBarのBackgroundColorを変更
  • UIViewControllerRepresentableでNavigationBarのStyleを変えたいViewを生成
  • NavigationBarを使うViewの.background()に上記のViewを設定

準備

import SwiftUI
import UIKit

struct NavigationConfigurator: UIViewControllerRepresentable {
    var configure: (UINavigationController) -> Void = { _ in }

    func makeUIViewController(context: UIViewControllerRepresentableContext<NavigationConfigurator>) -> UIViewController {
        UIViewController()
    }
    func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<NavigationConfigurator>) {
        if let nc = uiViewController.navigationController {
            self.configure(nc)
        }
    }

}

実際の使用例

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            Text("Don't use .appearance()!")
            .navigationBarTitle("Try it!", displayMode: .inline)
            .background(NavigationConfigurator { nc in
                // UIKitでNavigationBarのスタイルを変更するのと同じ方法でOK
                nc.navigationBar.barTintColor = .blue
                nc.navigationBar.titleTextAttributes = [.foregroundColor : UIColor.white]
            })
        }
    }
}

プレビュー

環境

2020年10月11日時点
Xcode 12.0.1
Swift 5.3
これ以外の環境については特に検証してないのでわからないですが、
SwiftUIが動く環境であれば可能だと思い込んでます

NavigationBarの背景色を変えたい

とりあえず、さくっとググってみるといくつかの記事で、コンストラクタとかの初期化処理の際にUINavigationBar.appearance()でしかできないとかかんとか、、、

たしかに、UINavigationBar.appearance()でも変えれることは変えれるが、
画面ごとに色を変えるのが困難(ってかこれだけなら無理なのでは、、、)

Stack Overflowありがとう!

SwiftUI update navigation bar title color
ちゃんと、いい感じに変更する方法を教えてくださってる方がいらっしゃりました

この方法のデメリット

プレビューをライブモードにしないとスタイルが反映されないです
ライブモードにすればいいだけなので、どうでもよいですね

ってことで、 UIViewControllerRepresentable を使っていい感じに背景色を変更できました
まだまだ、SwiftUIは成長途中なので、この子を使いこなさないといけなさそう