How change background color if using NavigationView in SwiftUI?

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.