Mandroid
Mandroid

Reputation: 239

NSOutlineView, how to get the selected cell

I want to get the selected cell from the NSOutlineView control. I found a solution here: How can I get the selected cell from a NSOutlineView?. It says

Use the delegate. willDisplayCell: is called when a cell changes its selection state.

However when I test it, I found that my willDisplayCell: is not be called.

Here's my code, it can be run normally, but the willDisplayCell: method has never been called. Where did I make a mistake? Thanks.

class TreeNode: NSObject{
    var name: String = ""
    private(set) var isLeaf: Bool = false
    var children: [TreeNode]?

    init(name: String, isLeaf: Bool){
        self.name = name
        self.isLeaf = isLeaf
        if !isLeaf{
            children = [TreeNode]()
        }
    }
}

class ViewController: NSViewController {

    @IBOutlet weak var sourceList: NSOutlineView!

    private var data = TreeNode(name: "Root", isLeaf: false)

    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.

        for i in 0..<10{
            let node = TreeNode(name: "name \(i)", isLeaf: i % 2 == 0)
            data.children?.append(node)
        }
    }
}

extension ViewController: NSOutlineViewDataSource {
    func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
        if let item = item as? TreeNode, !item.isLeaf {
            return item.children!.count
        }
        return 1
    }
    func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
        return !((item as? TreeNode)?.isLeaf ?? false)
    }
    func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
        if let item = item as? TreeNode {
            if item.isLeaf{
                return item
            }else{
                return item.children![index]
            }
        }
        return data
    }
}
extension ViewController: NSOutlineViewDelegate {

    func outlineView(_ outlineView: NSOutlineView, willDisplayCell cell: Any, for tableColumn: NSTableColumn?, item: Any) {
        print("called")
    }

    func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
        let cell: NSTableCellView?
        if let item = item as? TreeNode{
            cell = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue:  "DataCell"), owner: self) as? NSTableCellView
            cell?.textField?.stringValue = item.name
        }else{
            cell = nil
        }
        return cell
    }
}

enter image description here

Upvotes: 1

Views: 1223

Answers (1)

Mandroid
Mandroid

Reputation: 239

I've solved this problem myself. The following code is how to get the selected cell:

func getSelectedCell() -> NSTableCellView? {
    if let view = self.sourceList.rowView(atRow: self.sourceList.selectedRow, makeIfNecessary: false) {
        return view.view(atColumn: self.sourceList.selectedColumn) as? NSTableCellView
    }
    return nil
}

Now I can access the NSTextField control by the code getSelectedCell()?.textField.

Upvotes: 2

Related Questions