Is is possible to make NavigationView display all three columns on the iPad programmatically?

Here's an example of a NavigationView that uses the new 3-column layout:

Code Block
struct ContentView: View {
    var body: some View {
        NavigationView {
            PrimaryColumn()
            SupplementaryColumn()
            SecondaryColumn()
      }
    }
}


When the app starts on the iPad in the landscape mode, the supplementary and secondary columns are visible and the primary column can be opened with the Back button.

I'd like for the primary column to be visible immediately, because when the app starts the secondary column doesn't have any content. I could include some placeholder text, but the user would still have to take an extra step to expand the primary column, which is annoying.

With UIKit, I could use UISplitViewController with tripleColumn style, and expand the primary column manually by setting its display mode to twoBesideSecondary, for example.

Is this possible to achieve in SwiftUI?

Replies

Dip into UIKit in .onAppear, find the UISplitViewController, and set its preferredDisplayMode.


Code Block swift
var body: some Scene {
        WindowGroup {
            NavigationView {
                List(0..<10, rowContent: { i in
                    Text(String(describing: i))
                })
                .navigationTitle("One")
                ListTwo()
                VStack {
                    Text("Panel Three")
                }
                .navigationTitle("Three")
            }.onAppear {
                let controller = UIApplication.shared.windows.first { $0.isKeyWindow }!.rootViewController
                guard let split = controller?.children[0] as? UISplitViewController else {
                    print("not a split view")
                    return
                }
                split.preferredDisplayMode = .twoBesideSecondary
            }
        }
    }


Hey there,

I also stumbled upon this question today and SGB's solution works if you only use a NavigationView. I was using a TabView and nested the NavigationView into the tab and then the already provided solution doesn't work anymore.

After some trail and error I found a pretty simple solution which works for iOS 14:

Code Block swift
extension UISplitViewController {
open override func viewDidLoad() {
preferredDisplayMode = .oneBesideSecondary
}
}


You simply need to override the viewDidLoad from UISplitViewController and provide a preferredDisplayMode. With that you can change how many navigation levels are open.

Best,
Carsten