我遇到了最奇怪的问题NSOutlineView
:
- 一切都在故事板中设置,即大纲视图和两个
NSTableCellView
s
- 两个单元格视图基本相同,只有一个显示图标,另一个不显示
- 我可以通过按开始编辑项目(行)
Return
键,即NSTextField
这是我的一部分NSTableCellView
进入编辑模式。这是默认行为,到目前为止工作正常。
However:
- 编辑结束并且项目发生更改后,我使用故事板中的第二个表视图单元格(没有图标的单元格)。
- 现在按进入“编辑”模式
Return
钥匙不再起作用了!应用程序发出蜂鸣声,就这样。
最初加载时,两个单元格视图本身都是可编辑的。我证实了这一点。当某个项目首先显示在一个表格单元格视图中,然后显示在另一个表格单元格视图中(反之亦然)时,就会出现问题。
多次编辑一个项目效果很好,然后底层的NSTableCellView
不会改变。有人能解释一下这里发生的事情吗?
重现:
- 新的 Xcode 项目,Mac 应用程序
- Add an
NSOutlineView
用一列连接到您的视图控制器
- 添加两个表格视图单元格,“一”,“二”(标识符)
- 使用下面的代码
Steps:
- 运行应用程序,选择第二项
- 按“返回”,输入“绿色”,“返回”
- 再次按“Return”再次进入编辑模式
预期的:
Actual:
Code:
import Cocoa
class ViewController: NSViewController, NSOutlineViewDataSource, NSOutlineViewDelegate, NSTextFieldDelegate {
@IBOutlet var outlineView: NSOutlineView!
private var items = ["One", "Two"]
func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
return item == nil ? items.count : 0
}
func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
return items[index]
}
func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
return false
}
func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
guard let item = item as? String else { return nil }
NSLog("Vending cell view for: \(item)")
let identifier = item.contains("green") ? "Two" : "One"
if let view = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: identifier), owner: nil) as? NSTableCellView
{
view.textField?.stringValue = item
view.textField?.delegate = self
return view
}
return nil
}
func controlTextDidEndEditing(_ obj: Notification) {
NSLog("Did end editing")
guard
let textField = obj.object as? NSTextField,
let item = outlineView.item(atRow: outlineView.row(for: textField)) as? String else {
return
}
NSLog("Reloading item: \(item)")
let row = outlineView.row(for: textField)
items[row] = textField.stringValue
outlineView.reloadItem(item)
}
}
UPDATE:
我找到了解决方法,但这对我来说看起来像是一个错误。如果我打电话outlineView.reloadData(forRowIndexes:columnIndexes:)
就在之后reloadItem()
,问题不会发生。
不起作用(出现问题):
outlineView.reloadItem(item)
不起作用(outlineView的数据模型未更新,显示旧值):
outlineView.reloadData(forRowIndexes: IndexSet([row]), columnIndexes: IndexSet([0]))
这最终有效:
outlineView.reloadItem(item)
outlineView.reloadData(forRowIndexes: IndexSet([row]), columnIndexes: IndexSet([0]))
上述导致单元格视图被第二次请求。