18

I'm searching for a way to make the NavigationBar transparent. My NavigationView is in the root view in ContentView which contains a TabView.

import SwiftUI

struct ContentView: View {
var body: some View {
    TabView {
       HomeView().tabItem {
            Image(systemName: "house.fill")
            Text("Home")
        }.tag(1)
        NavigationView {
        SearchView()
            }

        .tabItem {
            Image(systemName: "magnifyingglass")
            Text("Search")
        }.tag(2)
}

The NavigationView Bar displays even after adding the following modifier in the root view.

init() { 
UINavigationBar.appearance().backgroundColor = .clear
UINavigationBar.appearance().isHidden = false

}

Below is the child view in which I'm trying to hide the navigationbar background.

import SwiftUI

struct FacilityView: View {


var perks = "Badge_NoPerks"
var image = "Image_Course6"
var courseName = "Course"

var body: some View {
    VStack {
        HStack {
            Image(image)
                .resizable()
                .aspectRatio(contentMode: .fill)
                .frame(width: UIScreen.main.bounds.width, height: 260)
        }
        VStack(alignment: .leading) {
            HStack {
                Image(perks)
            }
            HStack {
                Text(courseName)
                Spacer()
            }
        }
        .padding(.horizontal)
        Spacer()
    }.padding(.horizontal)
       .edgesIgnoringSafeArea(.top)
      .navigationBarTitle("Facility Details")


}

}

Jason Tremain
  • 1,259
  • 3
  • 20
  • 35
  • Are you trying to make the *entire* bar transparent, foreground and all? (I'm asking because you tried the `isHidden` modifier.) –  Aug 22 '19 at 20:23
  • Just the background. I need to keep the ability for someone to tap "Back" – Jason Tremain Aug 22 '19 at 22:07
  • Ow. This question *may* help, but I'm not sure: https://stackoverflow.com/questions/57508983/how-to-set-navigationview-background-colour-in-swiftui –  Aug 22 '19 at 22:22

5 Answers5

21

Try adding these to your init() modifiers:

UINavigationBar.appearance().barTintColor = .clear
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)

It worked for me in Xcode 11.2.1, iOS 13.2

Cliff
  • 329
  • 2
  • 9
  • It seems that there is no need to set `barTintColor`. just setting `backgroundImage` will do the trick. – Mohammad Rahchamani Feb 17 '20 at 11:06
  • 9
    Toobad this is global.I only want to do this on the home screen – TruMan1 Oct 02 '20 at 03:44
  • 4
    I would also add the shadowImage to this logic because else you will see a line after the transparent navigation bar. UINavigationBar.appearance().barTintColor = .clear UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default) UINavigationBar.appearance().shadowImage = UIImage() – thenextmillionaire Jan 01 '21 at 15:31
19

iOS 16+:

.toolbarBackground(.hidden, for: .navigationBar)

0xWood
  • 1,326
  • 12
  • 15
11

You can use this extension to UINavigationBar to toggle between transparent and default appearance.

extension UINavigationBar {
    static func changeAppearance(clear: Bool) {
        let appearance = UINavigationBarAppearance()
        
        if clear {
            appearance.configureWithTransparentBackground()
        } else {
            appearance.configureWithDefaultBackground()
        }
        
        UINavigationBar.appearance().standardAppearance = appearance
        UINavigationBar.appearance().compactAppearance = appearance
        UINavigationBar.appearance().scrollEdgeAppearance = appearance
    }
}

and in your view structs:

struct ContentView: View {
    init() {
        UINavigationBar.changeAppearance(clear: true)
    }
    var body: some View {
        NavigationView {
            ...
        }
    }
}
alionthego
  • 8,508
  • 9
  • 52
  • 125
  • If this worked for me it would fix all my problems. But seems like its not having any affect on the navigation bar. What am I doing wrong? – LateNate Apr 17 '21 at 13:09
  • @LateNate I've revised the answer to put it as an extension. Try this in your struct and see if it works. Works fine for me. – alionthego Apr 17 '21 at 13:28
  • Ahhh I see. Thanks so much. This is great! – LateNate Apr 17 '21 at 13:56
  • 1
    Be careful with this approach. SwiftUI sometimes inits structs for screens that aren't visible, for example when pointed to by a NavigationLink. – Edward Brey May 01 '21 at 13:06
  • Is there any work around that we can use this in other part apart from init like changing during scrolling – MrinmoyMk Jul 30 '21 at 22:41
6

For a transparent background without shadow:

init() {
    UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
    UINavigationBar.appearance().shadowImage = UIImage()
}

If the first solution does not work then:

init() {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithTransparentBackground()
    appearance.backgroundColor = .clear
    appearance.shadowColor = .clear
    UINavigationBar.appearance().standardAppearance = appearance
 }

enter image description here

Oleksandr B
  • 3,400
  • 1
  • 25
  • 28
-5
var body: some View {
    NavigationView {
        ZStack {
            Color.red
            Text("View1")
                .navigationBarHidden(false)
                .navigationBarTitle("Title")
        }
        .edgesIgnoringSafeArea(.top)
    }
}

enter image description here

UPDATE: 1.9.2022

NavigationView {
    ZStack {
        Color.red
        Text("View1")

    }
    .navigationBarTitleDisplayMode(.inline)
    .toolbar{
        ToolbarItem(placement: .principal) {
            Text("Title")
                .opacity(0.5)
        }
    }
    .edgesIgnoringSafeArea(.top)
}

enter image description here

Victor Kushnerov
  • 3,706
  • 27
  • 56