'SwiftUI: Get sidebar isCollapsed state on macOS
I'm using a NavigationView
to create a sidebar on macOS. I can toggle the sidebar using this code:
Button {
NSApp.keyWindow?.firstResponder?.tryToPerform(
#selector(NSSplitViewController.toggleSidebar(_:)), with: nil)
}
I'm now trying to display a label while the sidebar is hidden. Triggering this in the button will not work because the user can also hide the sidebar by resizing it.
There is an isCollapsed
property on NSSplitViewItem
and I assume this is what I might have to check for, but I have no clue how to access it with SwiftUI. Or is there another way to check for sidebar visibility?
Solution 1:[1]
The idea is to find NSSplitViewController
(which is still used internally as engine) and subscribe to observe its first split item (which is our sidebar) isCollapsed
state.
Tested with Xcode 13.3 / macOS 12.2.1
Here is main part:
// find split view through hierarchy
while sview != nil, !sview!.isKind(of: NSSplitView.self) {
sview = sview?.superview
}
guard let sview = sview as? NSSplitView else { return }
controller = sview.delegate as? NSSplitViewController // delegate is our controller
if let sideBar = controller?.splitViewItems.first { // now observe for state
observer = sideBar.observe(\.isCollapsed, options: [.new]) { [weak self] _, change in
if let value = change.newValue {
self?.sideCollapsed?.wrappedValue = value // << here !!
}
}
}
and usage like
SideViewInsideNavigationView()
.background(SplitViewAccessor(sideCollapsed: $collapsed)) // << inject finder !!
Complete findings and code is here
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Asperi |