我的基于视图的大纲视图为其行显示了一个自定义上下文菜单(右键单击菜单)。
菜单上的菜单项之一是“重命名...”,菜单项的representedObject
属性设置为大纲视图行表示的对象:
let menu = NSMenu()
// ...other menu items...
let renameItem = NSMenuItem(
title: "Rename...",
action: #selector(OutlineViewController.rename(_:)),
keyEquivalent: "")
renameItem.representedObject = object
menu.addItem(renameItem)
在操作方面,我想以编程方式使表格单元格中的文本字段可编辑。问题是,我不确定如何仅从表示的对象中获取对表格单元格的引用。
这是我的操作方法:
@IBAction func rename(_ sender: Any) {
guard let menuItem = sender as? NSMenuItem else { return }
guard let item = menuItem.representedObject else { return }
我可以获得表示对象(Int)的行:
let row = outlineView.row(forItem: item)
...和行视图(NSTableRowView):
let rowView = outlineView.rowView(atRow: row, makeIfNecessary: false)
我可以获得列索引(Int)和列(NSTableColumn):
let columnIndex = outlineView.column(withIdentifier: "TitleColumn")
let column = outlineView.tableColumns[columnIndex]
...并尝试获取单元格视图(NSTableCellView):
guard let cell = outlineView(outlineView, viewFor: column, item: item) as? NSTableCellView else {
return
}
最后,我尝试使文本字段可编辑:
guard let textField = cell.textField else {
return
}
textField.becomeFirstResponder()
所有这些测试都通过(我设置了断点),但没有任何反应:文本字段无法编辑(与双击时不同)。
我究竟做错了什么?
编辑我意识到当我打电话时:
outlineView(outlineView, viewFor: column, item: item)
这基本上NSOutlineViewDelegate
是我的视图控制器正在实现的方法,所以不是给我屏幕上已经存在的单元格,而是按需创建一个新副本。有点像打电话
UITableViewController.tableView(_:,cellForRowAt:)
// Data source method, creates or dequeues a new cell to pass
// back to the table for display
...而不是调用:
UITableView.cellForRowAt(_:) // 表格视图方法正确;如果 // 已经在屏幕上,则返回现有单元格,否则返回数据源(方法 // 上面)
因此,我应该查询大纲视图本身,而不是调用重新创建单元格视图的委托方法。但是,我能看到的唯一有意义的方法是:
func rowView(atRow row: Int, makeIfNecessary: Bool) -> NSTableRowView?
...返回一个 NSTable行视图...