Swift NSOutlineView,如何获取所选单元格

Swift NSOutlineView,如何获取所选单元格,swift,macos,cocoa,Swift,Macos,Cocoa,我想从NSOutlineView控件获取所选单元格。我在这里找到了一个解决方案:。上面说 使用委托。willDisplayCell:当单元格更改其选择状态时调用 然而,当我测试它时,我发现我的willDisplayCell:没有被调用 这是我的代码,它可以正常运行,但从未调用过willDisplayCell:方法。我在哪里犯了错误?谢谢 class TreeNode: NSObject{ var name: String = "" private(set) var isLeaf:

我想从NSOutlineView控件获取所选单元格。我在这里找到了一个解决方案:。上面说

使用委托。willDisplayCell:当单元格更改其选择状态时调用


然而,当我测试它时,我发现我的
willDisplayCell:
没有被调用


这是我的代码,它可以正常运行,但从未调用过
willDisplayCell:
方法。我在哪里犯了错误?谢谢

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
    }
}
类树节点:NSObject{
变量名称:String=“”
private(set)var isLeaf:Bool=false
变量子项:[TreeNode]?
init(名称:String,isLeaf:Bool){
self.name=名称
self.isLeaf=isLeaf
如果!岛{
children=[TreeNode]()
}
}
}
类ViewController:NSViewController{
@IBOutlet弱var源列表:NSOutlineView!
private var data=TreeNode(名称:“根”,isLeaf:false)
重写func viewDidLoad(){
super.viewDidLoad()
//加载视图后执行任何其他设置。
对于0..Int中的i{
如果let item=项目为?TreeNode,!item.isLeaf{
返回项目。子项!计数
}
返回1
}
func大纲视图(outlineView:NSOutlineView,isItemExpandable item:Any)->Bool{
返回!((项目名称为?TreeNode)?.isLeaf??错误)
}
func outlineView(outlineView:NSOutlineView,子索引:Int,of item项:Any?)->Any{
如果让项目=项目为?TreeNode{
如果item.isLeaf{
退货项目
}否则{
返回项目。子项![索引]
}
}
返回数据
}
}
扩展视图控制器:NSOutlineViewDeleteGate{
func outlineView(outlineView:NSOutlineView,willDisplayCell单元格:任意,对于tableColumn:NSTableColumn?,项:任意){
印刷品(“被称为”)
}
func outlineView(outlineView:NSOutlineView,viewFor tableColumn:NSTableColumn?,项目:任意)->NSView{
let cell:NSTableCellView?
如果让项目=项目为?TreeNode{
cell=outlineView.makeView(标识符为NSUserInterfaceItemIdentifier(rawValue:“DataCell”),所有者为self)为?NSTableCellView
单元格?.textField?.stringValue=item.name
}否则{
单元格=零
}
返回单元
}
}

我自己解决了这个问题。下面的代码是如何获取所选单元格:

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
}

现在我可以通过code
getSelectedCell()?.textField
访问
NSTextField
控件。我自己解决了这个问题。下面的代码是如何获取所选单元格:

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
}

现在我可以通过code
getSelectedCell()访问
NSTextField
控件?.textField

willDisplayCell:
和其他单元格方法由基于单元格的大纲视图调用。链接问题的答案不是一个好主意。是否要获取选择或在选择更改时需要触发器?@Willeke感谢您的回答。更确切地说,我希望在t中获取NSTextField控件他选择了显示节点名称的树节点。我知道
outlineViewSelectionDidChange:
方法,但我无法使用它获取NSTextField控件。
willDisplayCell
在任何地方都是错误的。从模型(数据源)获取信息或者使用Cocoa绑定。
willDisplayCell:
和其他单元格方法由基于单元格的大纲视图调用。链接问题的答案不是一个好主意。您希望获得选择还是希望在选择更改时触发?@Willeke感谢您的回答。更确切地说,我希望在他选择了显示节点名称的树节点。我知道
outlineViewSelectionDidChange:
方法,但我无法使用它获取NSTextField控件。
willDisplayCell
在任何地方都是错误的。从模型(数据源)获取信息或使用Cocoa绑定。这与
视图不一样吗(atColumn:row:MakeIfEssential:)
?您不能选择行和列。@Willeke,谢谢您的回复。但是为什么我不能选择行和列呢?这段代码对我的项目很有效,我用它来获得正确的单元格,正确的文本字段。一切似乎都正常。
selectedColumn
>>=0?我很惊讶它能工作(我尝试了,
view(atColumn:)
检查列是否<0并将其设置为0)@Willeke,是的,你是对的,
selectedColumn
始终是
-1
。但它仍然有效。起初,我对
atColumn
参数使用
0
,因为我只有一个表列,所以它有效。后来,我找到了
selectedColumn
属性,所以我使用了它,它仍然有效。我不知道为什么,但确实如此工作正常。我在Xcode 9.3 swift4上进行了测试。这与
视图(atColumn:row:makeifrequired:)不一样吗
?您不能选择行和列。@Willeke,谢谢您的回复。但是为什么我不能选择行和列呢?这段代码对我的项目很有效,我用它来获得正确的单元格,正确的文本字段。一切似乎都正常。
selectedColumn
>>=0?我很惊讶它能工作(我尝试了,
view(atColumn:)
检查列是否<0并将其设置为0)@Willeke,是的,你是对的,
selectedColumn
始终是
-1
。但它仍然有效。起初,我对
atColumn
参数使用
0
,因为我只有一个表列,所以它有效。后来,我找到了
selectedColumn
属性,所以我使用了它,它仍然有效。我不知道为什么,但确实如此工作正常。我在Xcode 9.3和swift4上测试。