There are a bunch of bugs or misbehaviors in the current (10.4) version of NSSplitView. Here are the ones I’ve needed to solve:
(1) While the split view respects the minimum and maximum coordinates if you drag the divider around yourself, it doesn’t respect them if you’ve set up the view to resize with the window, and you shrink the window.
(2) If you collapse a subview, any view in it that has keystroke focus retains it. You can still type in invisible text fields, navigate invisible tables, etc. Plus, all the text fields, tables, etc. inside the collapsed subview can still be tabbed through.
(3) The coordinates of the subviews are not automatically saved and restored, the way the column sizes and positions in a NSTableView are.
In my recent project, I fixed all these problems with delegate methods. If you implement
splitView:resizeSubviewsWithOldSize: and do the resizing yourself in the problem case, you can fix (1). If you implement
splitViewDidResizeSubviews:, you can do (3) and, if you check for when a subview has collapsed, you can make sure (2) doesn’t happen.
However, if you want to write less of your own code, there are other options. Even with a cursory search, I have found three NSSplitView replacements:
OASplitView from the Omni frameworks. Is a subclass of NSSplitView. Solves only (3).
KFSplitView from Ken Ferry. A subclass of NSSplitView. It solves (1) and (3). (2) still happens in its demo.
RBSplitView from Rainer Brockerhoff. Not a subclass of NSSplitView. Solves (1) and (3). Solves the first part of (2), but not the second.
Admittedly, the second part of (2) might not be possible in general-purpose framework code, since it can involve an invasive solution. I solved it in the code I was working on by subclassing the NSTableView located in the subview. In the subclass, I added an
_acceptsFirstResponder flag, a
setAcceptsFirstResponder: method to set the flag, and overrode
acceptsFirstResponder to use the flag.
With these changes, it was easy to take a table out of the tab chain when the subview was collapsed, by merely sending it the
set message. It would have been more onerous if I had to subclass multiple classes to get this same behavior in different types of widgets, in order to send the same
set message in them all.
You may be able to get the same behavior out of some controls by sending them a
setEnabled: message, but that wasn’t successful for me with tables.