Shadowman
Shadowman

Reputation: 12039

SwiftUI - 3 Column/Sidebar Layout with All Visible?

I'm experimenting with SwiftUI's new support for multi-column sidebar layouts. I know that I can do something like this:

struct SidebarContentView: View {
    
    var body: some View {
        NavigationView {
            List {
                ForEach(0...5, id: \.self) { i in
                    Text("\(i)")
                }
            }
            .listStyle(SidebarListStyle())
            .navigationTitle("List 1")
            
            List {
                ForEach(0...5, id: \.self) { i in
                    Text("\(i)")
                }
            }
            .navigationTitle("List 2")
            
            Text("Hello world")
                .font(.largeTitle)
                .navigationTitle("Content")
        }
        .navigationViewStyle(DoubleColumnNavigationViewStyle())
    }
}

To create my 3-column layout (2 navigation columns and then a larger content view), but initially that results in a view that looks like this:

enter image description here

I would have to hit the Back button in order to get the layout to look like this:

enter image description here

What I'd really like to have is all 3 columns be visible at the same time, without the need to hit a back button or anything, at least when an iPad is in landscape mode. An example would look like this:

enter image description here

Can anyone explain how I can achieve such a layout? I would want it to be active when my app runs on macOS or when on an iPad in landscape mode. In portrait mode I would be fine with the navigation style shown in the first screenshot, but want all panes to be visible otherwise. Any ideas?

Upvotes: 4

Views: 2448

Answers (1)

user15437479
user15437479

Reputation: 76

Update: Better solution

extension UISplitViewController {
    open override func viewDidLoad() {
        super.viewDidLoad()
        self.show(.primary)        
    }
}

===========================

Take a look at this github project: SwiftUI-Introspect

import Introspect

@main
struct ExampleApp: App {
    var body: some Scene {
        WindowGroup {
            NavigationView {
                Text("Primary View")
                Text("Supplementary View")
                Text("Secondary View")
                    // show primary view at startup
                    .introspectSplitViewController(customize: { splitViewController in
                        splitViewController.show(.primary)
                    })
            }
        }
    }
}
// Implement UISplitViewControlle selector
extension View {
    public func introspectSplitViewController(customize: @escaping (UISplitViewController) -> ()) -> some View {
        return inject(UIKitIntrospectionViewController(
            selector: { introspectionViewController in
                
                // Search in ancestors
                if let splitViewController = introspectionViewController.splitViewController {
                    return splitViewController
                }
                
                // Search in siblings
                return Introspect.previousSibling(containing: UISplitViewController.self, from: introspectionViewController)
            },
            customize: customize
        ))
    }
}

Upvotes: 2

Related Questions