When you are growing up on UIKit and never touch SwiftUI, you will probably never open this post because you imagine it is something like set a color to one property. But you are wrong.

You can call background(Color.red) on NavigationView, but it have no impact on background of your NavigationBar or anything else 🙇‍♂️. There is noting like navigationBar property in SwiftUI. Yes you can set a color on appeareanse with small UIKit “hack” UINavigationBar.appearance().backgroundColor = UIColor.red, but it is UIColor and it’s not probably what you really want.

Don’t give up, is there almost one solution, add a color with ignoring safe area in your contnent. Best practice is create new View, in my case it is Screen, which will wrapp content inside, after set color for navigationBar and then for your backgorund.

struct Screen<Content: View>: View {
    var body: some View {
        ZStack {
            navigationBarColor.edgesIgnoringSafeArea(edges)
            background
            content
        }
    }

    init(
        edges: Edge.Set = [.top],
        navigationBarColor: Color = .red,
        background: Color = .white,
        @ViewBuilder content: () -> Content
    ) {
        self.content = content()
        self.edges = edges
        self.navigationBarColor = navigationBarColor
        self.background = background
    }

    /// Content inside element
    private let content: Content
    private let edges: Edge.Set
    private let navigationBarColor: Color
    private let background: Color
}

Every new screen is wrapped in Screen element. With this little update you don’t must set every time your navigation bar color.

struct Screen_Previews: PreviewProvider {
    static var previews: some View {
        NavigationView {
            Screen {
                Text("Nah")
            }
        }
    }
}

Screen preview

Tip: When you remember my first post about AppStyle, then you can use it to improve this solution.

struct Screen<Content: View>: View {
    @Environment(\.style) var style: AppStyleProtocol

    var body: some View {
        ZStack {
            style.colors.main.edgesIgnoringSafeArea(edges)
            style.colors.background
            content
        }
    }

    /// Create screen View
    /// - Parameters:
    ///   - edges: Edges of navigation background, for use background color under `Home Indicator` use `[.top, .bottom]` edges
    ///   - content: Screen content
    init(
        edges: Edge.Set = [.top],
        @ViewBuilder content: () -> Content
    ) {
        self.content = content()
        self.edges = edges
    }

    /// Content inside element
    private let content: Content
    private let edges: Edge.Set
}