swiftswiftuisafearealayoutguide

How to make custom navigation bar background color to go beyond safe area in SwiftUI


I implemented a custom navigation bar which is simply a view with a title text and an arrow to dismiss the view. I want only the background color of the nav bar to go beyond the top safe area whilst the content respects the safe area constraints

Here's the code for custom nav bar:

struct CustomNavigationBar: View {
    
    @Environment(\.presentationMode) var presentationMode
    let title: String
    
    var body: some View {
        HStack {
            Button(action: {
                presentationMode.wrappedValue.dismiss()
            }, label: {
                Image(systemName: "chevron.left")
                    .font(.title2)
                    .foregroundColor(Globals.Color.background)
            })
            Spacer()
            Text(title)
                .font(.title2)
                .bold()
                .foregroundColor(Globals.Color.background)
            Spacer()
        }
        .padding()
        .background(Globals.Color.crimson)
    }
}

Here's the code for a sample view using the custom navigation bar:

var body: some View {
    ZStack {
        VStack {
            CustomNavigationBar(title: "Sample Title")
            Spacer()
        }
    }
}

Below I have attached a screenshot of current view:

Navigation bar view's red background stops at safe area]

Solution

  • You should put a ignoresSafeArea on the crimson background.

    struct CustomNavigationBar: View {
        
        @Environment(\.presentationMode) var presentationMode
        let title: String
        
        var body: some View {
            HStack {
                
                Button(action: {
                    presentationMode.wrappedValue.dismiss()
                }, label: {
                    Image(systemName: "chevron.left")
                        .font(.title2)
                        .foregroundColor(Color.white)
                })
                Spacer()
                Text(title)
                    .font(.title2)
                    .bold()
                    .foregroundColor(Color.white)
                Spacer()
                
            }
            .padding()
            .background(Color.red.ignoresSafeArea()) /// here!
        }
    }
    

    Result:

    Red background expands to fill screen, while inner text respects safe area