我是Swift的新手,并尝试学习如何使用NSOutlineView实现NSTreeController。我一直在关注几个显示这些示例的指南,但我一直收到错误。我按照一步一步的步骤和/或尝试运行他们的源代码(如果可用),但我得到了相同的错误。我认为Swift 4中有一些变化使得这些Swift 3示例产生错误。由于在Swift 4中没有很多例子,我决定在这里问一下这个问题。
我得到的错误是:
此类与密钥isLeaf不符合密钥值编码。
我认为错误来自为NSTreeController设置的密钥路径。
但是我不确定需要做些什么来解决错误。
我有一个名为Year的简单模型类。
class Year: NSObject {
var name: String
init(name: String) {
self.name = name
}
func isLeaf() -> Bool {
return true
}
}
我的视图控制器看起来像这样。
class ViewController: NSViewController, NSOutlineViewDataSource, NSOutlineViewDelegate {
@IBOutlet weak var outlineView: NSOutlineView!
@IBOutlet var treeController: NSTreeController!
override func viewDidLoad() {
super.viewDidLoad()
addData()
outlineView.delegate = self
outlineView.dataSource = self
}
func addData() {
let root = ["name": "Year", "isLeaf": false] as [String : Any]
let dict: NSMutableDictionary = NSMutableDictionary(dictionary: root)
dict.setObject([Year(name: "1999"), Year(name: "2000")], forKey: "children" as NSCopying)
treeController.addObject(dict)
}
func isHeader(item: Any) -> Bool {
if let item = item as? NSTreeNode {
return !(item.representedObject is Year)
} else {
return !(item is Year)
}
}
func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
if isHeader(item: item) {
return outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "HeaderCell"), owner: self)!
} else {
return outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "DataCell"), owner: self)!
}
}
}
当我运行该程序时,它不会引起任何问题,但是当我展开节点以显示根的两个子节点时,它会给出我上面提到的错误。
答案 0 :(得分:1)
由于isLeaf
在KVO中使用了NSOutlineView
,因此您必须在@objc
函数前添加isLeaf
:
@objc func isLeaf() -> Bool {
return true
}
答案 1 :(得分:1)
您要绑定到的类必须符合KVO。
因此,它必须是NSObject的子类。 而且objc运行时需要访问。
一种方法:
@objcMembers
class FileSystemItem: NSObject {
或者,您可以使用@objc注释每个字段/函数