swiftmacosswiftui

SwiftUI - How to disable sidebar from collapsing?


Gif to understand easier

Is there any way to disable collapsibility of SidebarListStyle NavigationViews?


Solution

  • EDIT: This method still works as of late 2022, and has never stopped working on any version of macOS (up to latest Ventura 13.1). Not sure why there are answers here suggesting otherwise. If the Introspection library changes their API you may need to update your calls accordingly, but the gist of the solution is the same.


    Using this SwiftUI Introspection library: https://github.com/siteline/SwiftUI-Introspect

    We can introspect the underlying NSSplitView by extending their functionality:

    public func introspectSplitView(customize: @escaping (NSSplitView) -> ()) -> some View {
        return introspect(selector: TargetViewSelector.ancestorOrSibling, customize: customize)
    }
    

    And then create a generic extension on View:

    public extension View {
        func preventSidebarCollapse() -> some View {
            return introspectSplitView { splitView in
                (splitView.delegate as? NSSplitViewController)?.splitViewItems.first?.canCollapse = false
            }
        }
    }
    

    Which can be used on our sidebar:

    var body: some View {
        (...)
        MySidebar()
            .preventSidebarCollapse()
    }