I want to change background color for full screen. I am using NavigationView
, and I want to set Gray color for background (not default white)
struct ContentView : View {
var body: some View {
NavigationView {
ScrollView {
Text("Example")
}
.navigationBarTitle("titl")
}
}
}
Setting .background(Color.red)
does not work in any place.
If you just embed your content in the NavigationView
within a ZStack
you should be able to throw the color in underneath your main content.
struct ContentView : View {
var body: some View {
NavigationView {
ZStack {
Color.red.edgesIgnoringSafeArea(.all)
ScrollView {
Text("Example")
}
.navigationBarTitle("title")
}
}
}
}
Adding to Mattis Schulte's answer, one of the side effects I've encountered is that the status bar will not inherit the background color.
However when you scroll a List (for example) up toward the top of the view and iOS switches to an inline title view (with the centered NavigationBarTitle) it does color in the status bar area leaving a fairly undesirable user experience.
The workaround I was able to use is:
import SwiftUI
let coloredNavAppearance = UINavigationBarAppearance()
struct ListView: View {
init() {
coloredNavAppearance.configureWithOpaqueBackground()
coloredNavAppearance.backgroundColor = .systemBlue
coloredNavAppearance.titleTextAttributes = [.foregroundColor: UIColor.white]
coloredNavAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
UINavigationBar.appearance().standardAppearance = coloredNavAppearance
UINavigationBar.appearance().scrollEdgeAppearance = coloredNavAppearance
}
var body: some View {
NavigationView {
Form {
Section(header: Text("General")) {
HStack {
Text("ListView #1")
Spacer()
Text("data")
.multilineTextAlignment(.trailing)
}
HStack {
Text("ListView #2")
Spacer()
Text("data")
.multilineTextAlignment(.trailing)
}
}
}
.navigationBarTitle("NavBar Title")
}
}
}
struct ListView_Previews: PreviewProvider {
static var previews: some View {
ListView()
}
}
Hope this helps someone else. Credit to https://sarunw.com/posts/uinavigationbar-changes-in-ios13/
A newest solution is having an extension for UINavigationController
, as below:
extension UINavigationController {
override open func viewDidLoad() {
super.viewDidLoad()
let standard = UINavigationBarAppearance()
standard.backgroundColor = .red //When you scroll or you have title (small one)
let compact = UINavigationBarAppearance()
compact.backgroundColor = .green //compact-height
let scrollEdge = UINavigationBarAppearance()
scrollEdge.backgroundColor = .blue //When you have large title
navigationBar.standardAppearance = standard
navigationBar.compactAppearance = compact
navigationBar.scrollEdgeAppearance = scrollEdge
}
}
OR, The old one:
Inside your struct initializer change UITableView
color, as below:
struct ContentView : View {
init() {
UITableView.appearance().backgroundColor = .red
}
var body: some View {
NavigationView {
ScrollView {
Text("Example")
}
.navigationBarTitle("title")
}
}
}
Just add this to the initializer of your code UIScrollView.appearance().backgroundColor = UIColor.red
. But unfortunately, this solution has many side effects.
One little hack that you can do is add a text view that doesnt have any text in it and add the background color to what you want, something like the following:
Text(" ")
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
.background(Color.red)
.edgesIgnoringSafeArea(.all)
Ok I just tried omar's solution, and unfortunately it doesn't work if there are any other views in the stack.
So the best answer I've seen for now that actually changes the underlying background color of the NavigationView
(in OP's original question) is just setting the background color on the UIView appearance, as eluded to in this answer :
UIView.appearance().backgroundColor = UIColor.red
Here is my solution as none of the others worked in my case so I thought I would share..
So for the Navigation header bar colour, add an initialiser like this:
struct ContentView: View {
init() {
UINavigationBar.appearance().backgroundColor = .red
}
var body: some View {
NavigationView {
ScrollView {
...
}
}
}
}
And then for editing the ScrollView background color, you can do something like this: I have done for ListView but you can do it for ScrollView.
struct ListBackgroundColor: ViewModifier {
let color: UIColor
func body(content: Content) -> some View {
content
.onAppear() {
UITableView.appearance().backgroundColor = self.color
//(Optional) Edit colour of cell background
UITableViewCell.appearance().backgroundColor = self.color
}
}
}
extension View {
func listBackgroundColor(color: UIColor) -> some View {
ModifiedContent(content: self, modifier: ListBackgroundColor(color: color))
}
}
UI Example https://imgur.com/a/TQ9c5Sc
The new way to do it
extension UINavigationController {
open override func viewDidLoad() {
super.viewDidLoad()
let standardAppearance = UINavigationBarAppearance()
standardAppearance.backgroundColor = .blue
standardAppearance.titleTextAttributes = [.foregroundColor: UIColor.white]
standardAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
navigationBar.standardAppearance = standardAppearance
navigationBar.compactAppearance = standardAppearance
navigationBar.scrollEdgeAppearance = standardAppearance
}}
If you need separate styles for compactAppearance
, scrollEdgeAppearance
extension UINavigationController {
open override func viewDidLoad() {
super.viewDidLoad()
let standardAppearance = UINavigationBarAppearance()
standardAppearance.backgroundColor = .blue
standardAppearance.titleTextAttributes = [.foregroundColor: UIColor.white]
standardAppearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
let compactAppearance = UINavigationBarAppearance()
compactAppearance.backgroundColor = .red
let scrollEdgeAppearance = UINavigationBarAppearance()
scrollEdgeAppearance.backgroundColor = .yellow
navigationBar.standardAppearance = standardAppearance
navigationBar.compactAppearance = compactAppearance
navigationBar.scrollEdgeAppearance = scrollEdgeAppearance
}}
For more read
it's quite complicated to change bg color for NavigationView and keep it working properly like minification / magnification during content scrolling and also keeping safe areas
NavigationView-color-customisation on github here i posted common problems and solutions about color customisation in SwiftUI app
also if you really want to change bg color in ALL navgiationViews, prev comment's first part about Extension on UINavigationController looks good
NavigationView in SwiftUI and UINavigationBar in UIKit are just as cumbersome, and I have a third-party open source solution for iOS system navigation bars that I hope will help you solve the problem.
Git repo: NXNavigationExtension
Change NavigationView color:
struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink {
Text("Pop")
.padding()
.useNXNavigationView(onPrepareConfiguration: { configuration in
// Page2
configuration.navigationBarAppearance.backgroundColor = .green
})
} label: {
Text("Push")
.padding()
.useNXNavigationView(onPrepareConfiguration: { configuration in
// Page1
configuration.navigationBarAppearance.backgroundColor = .red
})
}
}
.navigationViewStyle(.stack)
}
}
📝 example
For the nav bar in iOS 16 +
.toolbarBackground(.red, for: .navigationBar)
for iOS 14 and less
UINavigationBar.appearance().barTintColor = UIColor.red
for iOS 15
NavigationView {
ZStack(alignment: .top) {
GeometryReader { reader in
Color.red
.frame(height: reader.safeAreaInsets.top, alignment: .top)
.ignoresSafeArea()
}
// your content view
}
It's hard to get a "one size fits all solution" but in general it's possible to do this by introspecting the "hidden" view controller and setting it's background color. Best to use SwiftUI-Introspect for this. In your case:
struct ContentView : View {
var body: some View {
NavigationView {
ScrollView {
Text("Example")
}
.navigationBarTitle("titl")
.introspectViewController { vc in
vc.view.backgroundColor = .clear
}
}
}
}
It's possible that your view composition is different. To find the correct view debug your view hierarchy in Xcode and set the backgroundColor
on it. This could be via vc.parent
or vc.parent.subviews
or elsewhere in your view hierarchy.
Caveat: In my case I needed to use the modifier on my NavigationLink
destination.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.