Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI NavigationView collapse on scroll

Tags:

ios

swift

swiftui

How do I get the NavigationBar to collapse from large to inline when I scroll? Right now the ScrollView is scrolling it's content beneath the NavigationBar's title, but in front of the back button.

    var body: some View {
        NavigationView {
            ScrollView {
                VStack {
                    ForEach(0...5) { _ in
                        ExerciseView()
                    }
                }
                .padding()
            }
        }
        .navigationBarTitle("Testing", displayMode: .automatic)
like image 202
jjatie Avatar asked Jul 30 '19 13:07

jjatie


1 Answers

The first thing to note is that navigationBarTitle should be a modifier on ScrollView, not NavigationView.

var body: some View {
    NavigationView {
        ScrollView {
            VStack {
                ForEach(0...5) { _ in
                    ExerciseView()
                }
            }
            .padding()
        }
        .navigationBarTitle("Testing", displayMode: .automatic)
    }
}

From the documentation for navigationBarTitle:

This modifier only takes effect when this view is inside of and visible within a NavigationView.

Another thing to keep in mind, according to the documentation for displayMode:

case automatic

Inherit the display mode from the previous navigation item.

If you use .automatic, you're telling the NavigationView to use the same display mode as the previous navigation item, meaning that if you navigated from a view with a displayMode of .inline, then your new view will also inherit that display mode.

After moving the navigationBarTitle modifier to the ScrollView, however, your issue still remains - the scroll view scrolls underneath both the navigation bar title and the back button text as if the navigation bar's background is missing.

The answers to this question address a similar issue with a List scrolling underneath the status bar text, so I used their suggestion of adding padding to the ScrollView. That sort of works in that the scroll view now scrolls underneath the navigation bar properly, but the navigation bar still doesn't collapse from .large to .inline when you scroll.

This really just feels like a bug to me. There shouldn't be any need to set padding on the scroll view to begin with. The view doesn't know if it's going to be nested inside a NavigationView, so why should it have to specify padding just to make the navigation bar work properly?

In the meantime, I would just suggest setting the displayMode to .inline. At least that way everything will behave as you might expect.

like image 158
graycampbell Avatar answered Oct 21 '22 14:10

graycampbell