Is there no way to set a background color on NavigationView?

As of beta 5, the following doesn't work:


var body: some View {
  NavigationView {
    Text("Hello")
    .navigationBarTitle(Text("My App"))
  }
  .background(Rectangle()
  .foregroundColor(.blue))
}


Neither does just using the background modifier:


var body: some View {
  NavigationView {
    Text("Hello")
    .navigationBarTitle(Text("My App"))
  }
  .background(Color.blue)
}


Is this a bug, or is there an undocumented way to change the background color from the default white?


Just to be comprehensive, i've also tried setting the univeral appearance on UIView and UILabel:


UIView.appearance().backgroundColor = UIColor.green
UILabel.appearance().backgroundColor = UIColor.red


This does change the background color, but... the Text protocol doesn't seem to respond to UILabel, so the background of any Text contained within the NavigationView remains green (the UIView.appearance color).


If there's no possible way to change the NavigationView background color in the beta, that's ok. I just want to know if I should stop searching for answers or not. Or if there is an answer I'd like to know it 🙂

Accepted Reply

Ok I think I've solved it! I'm only hesitating because I'm not sure if it's the optimal way. 🤔


So it seems that the NavigationView has to be at the root, and a ZStack has to be at the root level of the NavigationView's children.


Then contained in that ZStack you can use a Rectangle for your background color with the fill attribute! The ZStack allows any child within its view to be overlayed on top instead of positioned underneath on the y axis or to the side on the x axis. Use edgesIgnoringSafeArea on the Rectangle if you want the background color to take up the entire screen.


I've then contained any Text view (or anything else) in a VStack within the ZStack for good form:


var body: some View {
       NavigationView {
            ZStack(alignment: .topLeading) {
                 Rectangle()
                      .fill(Color.blue)
                      .edgesIgnoringSafeArea(.all)
                 VStack(alignment: .leading) {
                      Text("Hello")
                           .navigationBarTitle(Text("My App")) 
                           .navigationBarItems(trailing: ProfileButton())
               }
          }
          .foregroundColor(.white)
     }
}


It's not quite intuitive, at least initially anyway. But I'd love to hear Apple's reasoning in the docs, or perhaps in a book on their Books store similar to their free "The Swift Programming Language".

Replies

try

UINavigationBar.appearance().backgroundColor = .green

Thanks, I have that enabled for the actual bar. But just to be clear, I mean the actual NavigationView. Not just the bar, but the background of the main view that contains the bar and every other child view.


There's nothing that I've tried that can change the background color of the actual NavigationView's main view. Neither does changing the background color of a ZStack or Group inside the NavigationView work.

Ok I think I've solved it! I'm only hesitating because I'm not sure if it's the optimal way. 🤔


So it seems that the NavigationView has to be at the root, and a ZStack has to be at the root level of the NavigationView's children.


Then contained in that ZStack you can use a Rectangle for your background color with the fill attribute! The ZStack allows any child within its view to be overlayed on top instead of positioned underneath on the y axis or to the side on the x axis. Use edgesIgnoringSafeArea on the Rectangle if you want the background color to take up the entire screen.


I've then contained any Text view (or anything else) in a VStack within the ZStack for good form:


var body: some View {
       NavigationView {
            ZStack(alignment: .topLeading) {
                 Rectangle()
                      .fill(Color.blue)
                      .edgesIgnoringSafeArea(.all)
                 VStack(alignment: .leading) {
                      Text("Hello")
                           .navigationBarTitle(Text("My App")) 
                           .navigationBarItems(trailing: ProfileButton())
               }
          }
          .foregroundColor(.white)
     }
}


It's not quite intuitive, at least initially anyway. But I'd love to hear Apple's reasoning in the docs, or perhaps in a book on their Books store similar to their free "The Swift Programming Language".

var body: some View {

ZStack {

Color.blue

}

.edgesIgnoringSafeArea(.all) // comment if you don't want the blue background in safeArea on iPhone X and next

}


The view will have a blue backgroundColor.


Working in Beta 6, but should work with previous too.



Hope this helps!