2
votes

So I've been playing around with SwiftUI and I can't seem to stack NavigationView correctly with ScrollView and ZStack.

I'm trying to achieve a view with a .black background. Code below:

MainView.swift

var body: some View {
    NavigationView {
        ChildView()
    }
}

ChildView.swift

var body: some View {
    ZStack {
        Color.black.edgesIgnoringSafeArea(.all)
        ScrollView {
            ...
        }
    }
} 

The above code gives me a black background but breaks the navigation bar behaviour.

How it looks: enter image description here

How it should look: enter image description here

So it seems like the the navigation doesn't go from the scrollEdgeAppearance to standardAppearance when scrolling.

Any ideas?

1
Did I answer your question? If so, please accept it as the solution.Bart van Kuik

1 Answers

4
votes

Put the ScrollView up as far as possible, otherwise the header animation will not work. The following code does what you want:

struct ChildView: View {
    var body: some View {
        ScrollView {
            VStack(spacing: 20) {
                ForEach(0..<40) { _ in
                    Text("Hello, World!")
                        .frame(maxWidth: .infinity)
                }
            }
            .background(Color.green.edgesIgnoringSafeArea(.all))
        }
        .navigationBarTitle("Discover")
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            ChildView()
        }
    }
}

To achieve a completely black background, even if you scroll up the bottom, you have to fiddle around in UINavigationController. While there, I also changed the navigation bar colors to achieve your look and feel. Note that this doesn't keep track of whether the user enabled dark mode or not.

extension UINavigationController {
    override open func viewDidLoad() {
        super.viewDidLoad()

        overrideUserInterfaceStyle = .dark

        let appearance = UINavigationBarAppearance()
        appearance.backgroundColor = UIColor.black
        appearance.titleTextAttributes = [.foregroundColor: UIColor.white]
        appearance.largeTitleTextAttributes = [.foregroundColor: UIColor.white]
        
        navigationBar.standardAppearance = appearance
        navigationBar.compactAppearance = appearance
        navigationBar.scrollEdgeAppearance = appearance
    }
}