Search code examples
swiftmacosappkitnsoutlineview

Hide Show/Hide button for group rows in NSOutlineView


My NSOutlineView has some group rows that cannot be collapsed, similar to Mail.app's inability to hide the "Mailboxes" group. I would expect the Show/Hide hover button to be disabled if the delegate's shouldCollapseItem method returns false, but that seems to not be the case.

I've tried manually disabling it with the following delegate:

func outlineView(_ outlineView: NSOutlineView, willDisplayOutlineCell cell: Any, for tableColumn: NSTableColumn?, item: Any) {
    if outlineView.delegate?.outlineView?(outlineView, shouldCollapseItem: item) == false {
        if let view = outlineView.delegate?.outlineView?(outlineView, viewFor: tableColumn, item: item) {
            if let button = view.subviews.first(where: { $0.identifier == NSOutlineView.showHideButtonIdentifier }) {
                button.isHidden = true
            }
        }
    }
}

But this doesn't work, since the view that is returned is just the NSTableCellView that will be rendered, and it doesn't have a superview at the time this delegate is called (so I can't look for sibling views).

I can access the Show/Hide button (which is an undocumented NSOutlineButtonCell instance) in the makeView(withIdentifier:owner:) delegate, but at this point I don't know if it will be representing one of the groups that can hidden or not.

There's got to be a way to do it, since Mail.app (and other apps) are able to conditionally disable the group's Show/Hide button.


Solution

  • Implement

    func outlineView(_ outlineView: NSOutlineView, shouldShowOutlineCellForItem item: Any) -> Bool
    

    and return false for the cells to be hidden