Pregunta

What is the most expedient way to expand NSOutlineView rows on a single click of the entire row? (not the disclosure triangle)

Is there a single setting for this? Or some magical mode setting that changes the behavior similar to source list style?

¿Fue útil?

Solución

Simplest way to do both expand and collapse together seems to be target/action with single clicks. I had tried overriding the selection functions in the outlineview delegate, and that worked for expansion but not collapse. Code below for single click expand/collapse:

[self.myOutlineView setTarget:self]; // Needed if not done in IB
[self.myOutlineView setAction:@selector(outlineViewClicked:)];
[self.myOutlineView setSelectionHighlightStyle:NSTableViewSelectionHighlightStyleNone];

- (void) outlineViewClicked:(NSOutlineView*)sender
{
    id clickItem = [sender itemAtRow:[self.itemsOutlineView clickedRow]];
    if (clickItem)
    {
        BOOL optionPressed = (([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask) == NSAlternateKeyMask);

        [sender isItemExpanded:clickItem] ? 
            [sender.animator collapseItem:clickItem collapseChildren:optionPressed] :
            [sender.animator expandItem:clickItem expandChildren:optionPressed];
    }
}

Expanding that to collapse siblings:

- (void) outlineViewClicked:(NSOutlineView*)sender
{
    id clickItem = [sender itemAtRow:[self.itemsOutlineView clickedRow]];

    if (!clickItem)
        return;

    BOOL optionPressed = (([[NSApp currentEvent] modifierFlags] & NSAlternateKeyMask) == NSAlternateKeyMask);

    // Collapse the sibling nodes (tree controller type NSTreeNode)
    for (NSTreeNode* node in ((NSTreeNode*)clickItem).parentNode.childNodes)
    {
        if (node != clickItem && [sender isItemExpanded:node]) 
            [sender.animator collapseItem:node];
    }

    [sender isItemExpanded:clickItem] ? 
        [sender.animator collapseItem:clickItem collapseChildren:optionPressed] : [sender.animator expandItem:clickItem expandChildren:optionPressed];
}

The optionPressed BOOL and the subsequent use in expandChildren and collapseChildren was suggested by @ben-haller, who noted that "an option-click on the disclosure triangle expands or collapses all of its contained items." (Quoted from About Outline Views) Ben's modification extends that option-click behavior to the "anywhere in the row" methods here.

Otros consejos

Swift version:

outlineView.target = self
outlineView.action = #selector(outlineViewClicked(_:))

@objc private func outlineViewClicked(_ sender: NSOutlineView) {
    expandOrCollapseRow(outlineView: sender)
}

private func expandOrCollapseRow(outlineView: NSOutlineView) {
    if let clickedItem = outlineView.item(atRow: outlineView.clickedRow) {
        if  outlineView.isItemExpanded(clickedItem) {
            outlineView.animator().collapseItem(clickedItem)
        } else {
            outlineView.animator().expandItem(clickedItem, expandChildren: true)
        }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top