4

In my app I want to hide UINavigationBar's bottom line. For that I use the appearance() accessor for UINavigationBar. Like so:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    let contentView = ContentView()

    if let windowScene = scene as? UIWindowScene {
        let window = UIWindow(windowScene: windowScene)
        window.rootViewController = UIHostingController(rootView: contentView)
        self.window = window
        window.makeKeyAndVisible()
        
        UINavigationBar.appearance().isTranslucent = false
        UINavigationBar.appearance().shadowImage = UIImage()
        UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
        UINavigationBar.appearance().barTintColor = .white
    }
}

But when I do so the content of views being pushed from main view get overlapped by navigation bar. For some reason when I set isTranslucent to true the pushed view works normally, but in that case navigation bar is, well, totally translucent and any content on scroll is visible behind it, I don't want that behavior.

Here is the code of my views:

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(
                    destination: AnotherView(),
                    label: {
                        Text("Screen 1")
                    })
                Spacer()
            }
            .navigationBarTitleDisplayMode(.inline)
        }
    }
}

struct AnotherView: View {
    var body: some View {
        VStack {
            Text("Screen 2")
            Spacer()
        }
    }
}

How do I keep navigation bar totally opaque with no bottom line and make pushed view work normally?

overllaping

A. Buksha
  • 830
  • 9
  • 14

1 Answers1

0

Thanks to Asperi I followed accepted answer here

So I ended up modifying navigation bar via background modifier. The code I have now:

struct NavigationConfiguration: UIViewControllerRepresentable {
    
init() {
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.shadowColor = .clear
        navBarAppearance.backgroundColor = .white
        UINavigationBar.appearance().standardAppearance = navBarAppearance
    }
    
func makeUIViewController(
        context: UIViewControllerRepresentableContext<NavigationConfiguration>
    ) -> UIViewController {
        UIViewController()
    }
    
func updateUIViewController(_ uiViewController: UIViewController,
                                context: UIViewControllerRepresentableContext<NavigationConfiguration>) {}
    
}

And in my view:

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(
                    destination: AnotherView(),
                    label: {
                        Text("Screen 1")
                    })
                Spacer()
            }
            .navigationBarTitleDisplayMode(.inline)
            .background(NavigationConfiguration())
        }
    }
}
A. Buksha
  • 830
  • 9
  • 14