How To Set NavigationView Background Colour in SwiftUI
It is same as UINavigationBar
. But since there is no direct api yet, you can change it using appearance
:
UINavigationBar.appearance().backgroundColor = .orange
UINavigationBar.appearance().tintColor = .green
UINavigationBar.appearance().barTintColor = .yellow
UINavigationBar.appearance().titleTextAttributes = [.foregroundColor: UIColor.red]
UINavigationBar.appearance().largeTitleTextAttributes = [.foregroundColor: UIColor.red]
You should put this somewhere that you sure the compiler reads like inside the init()
method.
Note that some of these will not work below Xcode 11 beta 5.
How to change background color of the NavigationView in SwiftUI?
First look at this result:
As you can see, you can set the color of each element in the View hierarchy like this:
struct ContentView: View {
init(){
UINavigationBar.appearance().backgroundColor = .green
//For other NavigationBar changes, look here:(https://stackoverflow.com/a/57509555/5623035)
}
var body: some View {
ZStack {
Color.yellow
NavigationView {
ZStack {
Color.blue
Text("Some text")
}
}.background(Color.red)
}
// iOS 16 - No need for tweaking the appearance
/* .toolbarBackground(.green, in: .navigationBar) */
}
}
And the first one is window
:
window.backgroundColor = .magenta
The issue you faced is we can not remove the background color of SwiftUI's HostingViewController
(yet), so you can't see the navigationView
(What you called) through the views hierarchy. You should wait for the API or try to fake the navigation view (not recommended).
SwiftUI background color of the screen with NavigationView
Updated:
with putting Color as ignoresSafeArea!
import SwiftUI
struct ContentView: View {
var body: some View {
NavigationView {
ZStack {
Color
.red
.ignoresSafeArea() // <<: Here
Color
.yellow
.cornerRadius(20)
.padding()
}.navigationTitle("Today")
.navigationBarItems(leading: Text("some texts"))
}
}
}
SwiftUI NavigationView background color
You could introduce a custom ViewModifier as described here.
Working example:
import SwiftUI
struct NavigationBarModifier: ViewModifier {
var backgroundColor: UIColor?
init(backgroundColor: UIColor?) {
self.backgroundColor = backgroundColor
}
func body(content: Content) -> some View {
ZStack{
content
VStack {
GeometryReader { geometry in
Color(self.backgroundColor ?? .clear)
.frame(height: geometry.safeAreaInsets.top)
.edgesIgnoringSafeArea(.top)
Spacer()
}
}
}
}
}
extension View {
func navigationBarColor(_ backgroundColor: UIColor?) -> some View {
self.modifier(NavigationBarModifier(backgroundColor: backgroundColor))
}
}
struct MyContentView: View {
var body: some View {
NavigationView {
ScrollView {
VStack(spacing: 8) {
Text("One")
.roundedContainer()
Text("Two")
.roundedContainer()
}
.padding()
}
.background(Color(.systemGroupedBackground))
.navigationBarTitle("Summary", displayMode: .large)
.navigationBarColor(.systemGroupedBackground)
}
}
}
SwiftUI changing navigation bar background color for inline navigationBarTitleDisplayMode
I think I have what you want. It is VERY touchy... It is a hack, and not terribly robust, so take as is...
I got it to work by having your modifier return a clear NavBar, and then the solution from this answer works for you. I even added a ScrollView to ThirdView() to make sure that scrolling under didn't affect in. Also note, you lose all of the other built in effects of the bar like translucency, etc.
Edit: I went over the code. The .navigationViewStyle was in the wrong spot. It likes to be outside of the NavigaionView(), where everything else needs to be inside. Also, I removed the part of the code setting the bar color in FirstView() as it was redundant and ugly. I hadn't meant to leave that in there.
struct NavigationBarModifier: ViewModifier {
var backgroundColor: UIColor?
var titleColor: UIColor?
init(backgroundColor: Color, titleColor: UIColor?) {
self.backgroundColor = UIColor(backgroundColor)
let coloredAppearance = UINavigationBarAppearance()
coloredAppearance.configureWithTransparentBackground()
coloredAppearance.backgroundColor = .clear // The key is here. Change the actual bar to clear.
coloredAppearance.titleTextAttributes = [.foregroundColor: titleColor ?? .white]
coloredAppearance.largeTitleTextAttributes = [.foregroundColor: titleColor ?? .white]
coloredAppearance.shadowColor = .clear
UINavigationBar.appearance().standardAppearance = coloredAppearance
UINavigationBar.appearance().compactAppearance = coloredAppearance
UINavigationBar.appearance().scrollEdgeAppearance = coloredAppearance
UINavigationBar.appearance().tintColor = titleColor
}
func body(content: Content) -> some View {
ZStack{
content
VStack {
GeometryReader { geometry in
Color(self.backgroundColor ?? .clear)
.frame(height: geometry.safeAreaInsets.top)
.edgesIgnoringSafeArea(.top)
Spacer()
}
}
}
}
}
extension View {
func navigationBarColor(backgroundColor: Color, titleColor: UIColor?) -> some View {
self.modifier(NavigationBarModifier(backgroundColor: backgroundColor, titleColor: titleColor))
}
}
struct FirstView: View {
@State private var selection: String? = nil
var body: some View {
NavigationView {
GeometryReader { _ in
VStack {
Text("This is the first view")
NavigationLink(destination: SecondView(), tag: "SecondView", selection: $selection) {
EmptyView()
}
Button(action: {
self.selection = "SecondView"
print("Go to second view")
}) {
Text("Go to second view")
}
}
.navigationTitle("First")
.navigationBarTitleDisplayMode(.inline)
.navigationBarColor(backgroundColor: .red, titleColor: .black)
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
struct SecondView: View {
@State private var selection: String? = nil
var body: some View {
VStack {
Text("This is the second view")
NavigationLink(destination: ThirdView(), tag: "ThirdView", selection: $selection) {
EmptyView()
}
Button(action: {
self.selection = "ThirdView"
print("Go to third view")
}) {
Text("Go to third view")
}
}
.navigationTitle("Second")
.navigationBarTitleDisplayMode(.inline)
.navigationBarColor(backgroundColor: .blue, titleColor: .black)
}
}
struct ThirdView: View {
var body: some View {
ScrollView {
ForEach(0..<50) { _ in
Text("This is the third view")
}
}
.navigationTitle("Third")
.navigationBarTitleDisplayMode(.inline)
.navigationBarColor(backgroundColor: .green, titleColor: .black)
}
}
Related Topics
How to Generate a Random Number in a Range (10...20) Using Swift
Get Class Name of Object as String in Swift
How to Use Swift'S Codable to Encode into a Dictionary
When Are Argument Labels Required in Swift
Nsdate Timeintervalsince1970 Not Working in Swift
The "++" and "--" Operators Have Been Deprecated Xcode 7.3
Send Data from Tableview to Detailview Swift
Why Optional Constant Does Not Automatically Have a Default Value of Nil
What Is the 'Open' Keyword in Swift
Non-'@Objc' Method Does Not Satisfy Optional Requirement of '@Objc' Protocol
Initialize @Stateobject With a Parameter in Swiftui
Deleting List Elements from Swiftui'S List