0
votes

I have an NSOutlineView where I'm trying to implement "search & replace" ability but the problem is that all nodes are not getting expanding.

let nodes : [NSTreeNode] = self.getNode(contains: "any word")

for node in nodes {
  self.outlineView.expandItem(node.parent) // that only work for short index path

  let row = self.outline.row(forItem: item)
    if row >= 0 {
      self.outlineView.scrollRowToVisible(row)
      self.outlineView.selectRowIndexes(IndexSet(integer: row), byExtendingSelection: false)
    }
}

The problem is that nodes at certain level doesn't get expanded.
How can I start expanding NSTreenode(s) starting from the initial parent node to the last child parent that contains my search?

1
How about using recursion? - matt
How about iterating over node.indexPath? - Willeke
Hi matt, yes recursion, but recursion of the parent? - Mike97
Hi Willeke, I can make it work this way: func asyncExpand(item: NSTreeNode?, expandParentOnly: Bool) { var parents : [NSTreeNode] = [NSTreeNode]() var parent : NSTreeNode? = item?.parent repeat { if (parent != nil) { parents.insert(parent!, at: 0) } parent = parent?.parent } while parent != nil for n in parents { DispatchQueue.main.async { self.outline.expandItem(n) } } if !expandParentOnly { DispatchQueue.main.async { self.outline.expandItem(item) } } } - Mike97
Please show me a possible recursion using IndexPath - Mike97

1 Answers

1
votes

Recursion, expand the parent before expanding the node:

func expandNode(_ node:NSTreeNode) {
    if let parent = node.parent {
        if !outlineView.isItemExpanded(parent) {
            self.expandNode(parent)
        }
    }
    outlineView.expandItem(node)
}

self.expandNode(node)

Iterating over node.indexPath:

var treeNode = treeController.arrangedObjects
node.indexPath.forEach { index in
    treeNode = treeNode.children![index]
    if !outlineView.isItemExpanded(treeNode) {
        outlineView.expandItem(treeNode)
    }
}