NavigationSplitView column visibilty does not work on iPhone

1k Views Asked by At

I have a two column NavigationSplitView with a linked NavigationSplitViewVisibility variable. On the iPad everything works as expected. Tapping on the “Go to Detail View” in the sidebar will go to the Detail view. However on the iPhone nothing happens. Any ideas how to resolve this.
Thanks
Here is the code:

struct ContentView: View {
    @State var visibility:NavigationSplitViewVisibility = .all
    var body: some View {
        NavigationSplitView( columnVisibility:$visibility) {
            Text("Go to Detail View" )
                .onTapGesture {
                    visibility = .detailOnly
                }
        } detail: {
            Text( "Show Sidebar")
                .onTapGesture {
                    visibility = .all
                }
        }
    }
}
1

There are 1 best solutions below

1
On

NavigationSplitView doesn't show multiple columns in an iPhone, apart from larger ones (e.g iPhone 14 Pro Max) in landscape.

From Apple's documentation

On watchOS and tvOS, and with narrow sizes like on iPhone or on iPad in Slide Over, the navigation split view collapses all of its columns into a stack, and shows the last column that displays useful information. … For rows in a list that have NavigationLink instances, the list draws disclosure chevrons while in the collapsed state.

If you use NavigationLinks in the sidebar, the NavigationSplitView on an iPhone works just like a regular NavigationStack. On larger devices the contents of detail is only displayed when no link is selected.

In the example below, tapping the "Hide sidebar" button would do nothing, so I've added a horizontalSizeClass Environment variable, which allows the button to be hidden on smaller devices.

struct ContentView: View {
    
    let names = ["Fred", "Joe", "Bill"]
    
    @State var visibility: NavigationSplitViewVisibility = .all
    @Environment(\.horizontalSizeClass) var horizontalSizeClass
    
    var body: some View {
        NavigationSplitView(columnVisibility: $visibility) {
            List {
                ForEach(names, id: \.self) { name in
                    NavigationLink(name, destination: Text(name))
                }
                
                if horizontalSizeClass == .regular {
                    Button("Hide sidebar") {
                        withAnimation {
                            visibility = .detailOnly
                        }
                    }
                }
            }
        } detail: {
            Text("Select a name")
        }
    }
}