NavigationSplitViewVisibility.detailOnly not working in macOS

66 Views Asked by At

I've been having lots of problems with NavigationSplitView in SwiftUI under macOS (14.3 if it matters). The latest one is this: NavigationSplitViewVisibility.detailOnly doesn't seem to do anything, it just reverts to showing the 3 original columns. If anyone knows how to actually trigger NavigationSplitView to only display the detail area I will be eternally grateful.

This is the code that is not working:

import SwiftUI

struct ContentView: View {
    @State private var columnVisibility: NavigationSplitViewVisibility = .all
    private var cvString: String { "\(columnVisibility)"}
    
    var body: some View {
        NavigationSplitView(columnVisibility: $columnVisibility) {
            VStack {
                Text("Sidebar")
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
            }
            .background(.red)
        } content: {
            VStack {
                Text("Content")
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
            }
            .background(.orange)
        } detail: {
            VStack {
                Spacer()
                Text("Detail")
                    .frame(maxWidth: .infinity, maxHeight: .infinity)
                
                HStack {
                    Text("Current Visibility:")
                        .bold()
                    
                    Text("\(cvString)")
                        .fontDesign(.monospaced)
                }
                
                Button("Next Visibility") {
                    self.columnVisibility = columnVisibility.next()
                }
                
                Spacer()
            }
            .background(.green)
        }
    }
}

// Extension just to toggle between Visibilities
extension NavigationSplitViewVisibility {
    func next() -> NavigationSplitViewVisibility {
        switch self {
        case .all: print("All -> DetailOnly"); return .detailOnly
        case .detailOnly: print("DetailOnly -> DoubleColumn"); return .doubleColumn
        case .doubleColumn: print("DoubleColumn -> All"); return .all
        default:
            print("Not handled.")
            return self
        }
    }
}
1

There are 1 best solutions below

1
Sweeper On BEST ANSWER

This is by-design. From the documentation of NavigationSplitViewVisibility,

Some platforms don’t respect every option. For example, macOS always displays the content column.

So the NavigationSplitViewVisibility values are more of a "suggestion".

You may argue that .detailOnly on macOS should at least be like .doubleColumn instead of .all, but either way a "true" .detailOnly is not supported.