Reputation: 822
I'm trying to implement an NSSplitView similar to Xcode where you can collapse a view by dragging its handle to under half its width and it will collapse automatically. I have that part working, but I need to update the state of a button in the toolbar when this happens. I tried listening to splitViewDidResizeSubviews and checking if the splitView's view is collapsed, but that method fires 16 times with collapsed == true, so I don't think I want to update the button's state 16 times. Is there a cleaner way to do this? I'm new to Cocoa, but from what I've seen, I would expect there to be some way to just say bind this button's state to the isCollapsed property and be done with it. Does such a thing exist?
Upvotes: 1
Views: 862
Reputation: 2624
If you subclass your NSSplitViewController
you can add a listener for the SplitViewItem's isCollapsed
property:
class MySplitViewController: NSSplitViewController {
var observer: NSKeyValueObservation?
override func viewDidLoad() {
super.viewDidLoad()
// Do view setup here.
let sideViewSplitViewItem = splitViewItems[0]
observer = sideViewSplitViewItem.observe(\.isCollapsed, options: [.initial, .new]) {splitViewItem, _ in
print("Sidebar collapsed state changed to: \(splitViewItem.isCollapsed)")
}
}
}
Upvotes: 1
Reputation: 438
While NSSplitView
has no event or observable property for when one of it's subviews is "collapsed", the immediate subview itself will have its hidden
property set to YES
.
So you can either observe the subview's hidden
property yourself, or if you're creating your own custom subview of NSView
, you can override the -(void) setHidden:(BOOL)hidden
to catch the event.
I do the latter, and it works correctly every time.
-(void)setHidden:(BOOL)hidden
{
[super setHidden:hidden];
// Insert code to react to the "collapsed" event here.
// (You're likely going to tell your parent view,
// self.window.windowController, or something.)
}
Of course the setHidden
method / hidden
property can in theory be called for purposes other than from NSSplitView
"collapsing" your view, but this is very unlikely to ever happen in practice.
Upvotes: 0
Reputation: 6918
The best way to see what bindings are available is to check the docs, specifically the Cocoa Bindings Reference (look in the sidebar for the view you're after).
NSSplitView
doesn't have the binding you describe, so I think you're on the right track with your current approach. Of course, you don't need to update the button's state sixteen times, just check it's value each time, and update it if needs be. It might seem a bit wasteful, but checking the value of a bool is a very cheap operation, and you won't notice any kind of performance hit.
Upvotes: 0