😎
SwiftUIのNavigationViewで画面全体に背景色を適用する
SwiftUI
のNavigationView
で画面全体に背景色を適用したいときはZStack
を利用します。
struct ContentView: View {
var body: some View {
NavigationView {
ZStack {
Color.green.edgesIgnoringSafeArea(.all)
Text("Hello, SwiftUI")
.font(.title)
}
.navigationTitle("NavigationView")
}
}
}
しかし、この方法では以下のようにNavigationView
のタイトルがインラインで表示された時に期待通りになりません。
struct ContentView: View {
var body: some View {
NavigationView {
ZStack {
Color.green.edgesIgnoringSafeArea(.all)
Text("Hello, SwiftUI")
.font(.title)
}
.navigationTitle("NavigationView")
.navigationBarTitleDisplayMode(.inline)
}
}
}
これを回避するにはUIKitのUINavigationBarAppearance
を使ってNavigationBar
の色を指定します。
let coloredNavAppearance = UINavigationBarAppearance()
struct ContentView: View {
init() {
coloredNavAppearance.configureWithOpaqueBackground()
coloredNavAppearance.backgroundColor = UIColor.init(red: 41/255, green: 199/255, blue: 50/255, alpha: 1.0)
// coloredNavAppearance.titleTextAttributes = [.foregroundColor: UIColor.black]
// coloredNavAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.black]
UINavigationBar.appearance().standardAppearance = coloredNavAppearance
UINavigationBar.appearance().scrollEdgeAppearance = coloredNavAppearance
}
var body: some View {
NavigationView {
ZStack {
Color(red: 41/255, green: 199/255, blue: 50/255, opacity: 1.0).edgesIgnoringSafeArea(.all)
Text("Hello, SwiftUI")
.font(.title)
}
.navigationTitle("NavigationView")
.navigationBarTitleDisplayMode(.inline)
}
}
}
上記の処理はアプリの中で一度だけ実行すれば良さそうです、iOS14以降であれば@main
のAppクラスに実装するとことで実現できそうです。
@main
struct MyApp: App {
init() {
let coloredNavAppearance = UINavigationBarAppearance()
coloredNavAppearance.configureWithOpaqueBackground()
coloredNavAppearance.backgroundColor = UIColor.init(red: 41/255, green: 199/255, blue: 50/255, alpha: 1.0)
UINavigationBar.appearance().standardAppearance = coloredNavAppearance
UINavigationBar.appearance().scrollEdgeAppearance = coloredNavAppearance
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
また、backgroundColorには透過色を指定するだけでも良さそうです。例えばUINavigationController
のviewDidLoad
を拡張してbackgroundColorにclear
を指定すると背景色を全体に表示させることができました。
extension UINavigationController {
override open func viewDidLoad() {
super.viewDidLoad()
let appearance = UINavigationBarAppearance()
appearance.configureWithTransparentBackground()
appearance.backgroundColor = UIColor.clear
navigationBar.standardAppearance = appearance
}
}
記事が参考にったらいいねしていただけると嬉しいです。
Discussion
こちらの記事に細かい実装が載っている。