TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

Day 42: Moonshot Challenge - NavigationView bar background color issue

Forums > 100 Days of SwiftUI

In the moonshot challenge, after breaking the ContentView into two separate views (one for grid layout and one for list layout), everything looks fine with the grid layout. However, the list layout results in the background of the NavigationView title/tool bar area to use the system color rather than the custom default background color.

I followed along with Paul's solution video, and I don't see any difference in my code to his.

Has anyone else experienced this in their project?

1      

I've discovered what was causing the NavigationView background in the bar area to not show the custom color used by the rest of app, when displaying a custom List View (note: I didn't have the problem with the Grid View):

Although the iOS deployment target is correctly set to iOS 15, my simulator was set to be an iPhone 14, which runs iOS 16 as a minimum iOS version. I'm not really sure why this is an issue, but it guess it is. I think the NavigationView is deprecated in iOS 16 so that may have something to do with it.

To confirm this, I ran the same code using the iPhone 13 simulator, and voila! the color is set correctly like in the solution video shown by Paul. Here's a comparison of the same code running on both simulators so you can see the difference:

image.pngimage.png

Hmm, so how to make this work with both an iOS 15 device as well as the new iPhone 14?

At first I found some code that allows you to explicitly set the NavigationBar's background (including the title bar area) in the ContentView's initializer:

    init() {
        let navBarAppearance = UINavigationBarAppearance()
        navBarAppearance.configureWithOpaqueBackground()
        navBarAppearance.backgroundColor = UIColor(Color.darkBackground)
        UINavigationBar.appearance().scrollEdgeAppearance = navBarAppearance
    }

This mostly works, but some styling looks a bit off, and there is a weird chunky bit of the black background that shows through between the list and the NavigationView's title area when moving to/from a child view, which looks bad.

A different approach I found is to use a NavigationStack instead of the NavigationView. However, this is only available in iOS 16. If you still want your app to target iOS 15 and have it work in iOS 16 on the new iPhones (which I think most people do) then you will need to use an availability condition to use the NavigationStack if iOS 16 is running, and fall back to the NavigationView otherwise. Note: with the NavigationStack I had to add a couple view modifiers to make it display properly (see sample below).

Here is a stubbed out code snippet to give you the idea, but note that this solution too wasn't perfect, as it had some strange animation anomalies and some styling differences from the NavigationView that I'm not sure are intentional or not (maybe it's just the simulator acting werid, as I don't have an actual device running iOS 16 to test with). In any event, I haven't found a solution I'm totally satisfied with, but I guess it's workable.

Maybe someone else knows an easier fix or one that works better? Please leave a post if you know a better solution.

            if #available(iOS 16.0, *) {
                NavigationStack {
                    Group {
                        //Grid or List view here
                    }
                    .toolbar{
                        // Button code here
                    }
                    .navigationTitle("Moonshot")
                    .background(.darkBackground)
                    .preferredColorScheme(.dark)
                    .toolbarBackground(Color.darkBackground, for: .navigationBar)
                    .toolbarBackground(.visible, for: .navigationBar)
                }
            } else {
                // Fallback on earlier versions
                NavigationView {
                    Group {
                        //Grid or List view here
                    }
                    .toolbar{
                        // Button code here
                    }
                    .navigationTitle("Moonshot")
                    .background(.darkBackground)
                    .preferredColorScheme(.dark)
                }
            }

1      

Hacking with Swift is sponsored by String Catalog.

SPONSORED Get accurate app localizations in minutes using AI. Choose your languages & receive translations for 40+ markets!

Localize My App

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.