Swift 如何在没有绑定的情况下使用NSOutlineView

Swift 如何在没有绑定的情况下使用NSOutlineView,swift,macos,cocoa,Swift,Macos,Cocoa,我的数据如下所示: let keysDetails:[字符串:任意]=[ “卡多巴格”:[ “locDict”:[ “在”:“添加”, “ae”:“添加” ], “jsonDict”:[ “在”:“添加到包中”, “ae”:“添加到包中” ], “路径”:“somepath” ], “kShopTab”:[ “locDict”:[ “be_fr”:“商店”, “be_nl”:“商店” ], “jsonDict”:[ “be_fr”:“商店”, “be_nl”:“商店” ], “路径”:“some

我的数据如下所示:

let keysDetails:[字符串:任意]=[
“卡多巴格”:[
“locDict”:[
“在”:“添加”,
“ae”:“添加”
],
“jsonDict”:[
“在”:“添加到包中”,
“ae”:“添加到包中”
],
“路径”:“somepath”
],
“kShopTab”:[
“locDict”:[
“be_fr”:“商店”,
“be_nl”:“商店”
],
“jsonDict”:[
“be_fr”:“商店”,
“be_nl”:“商店”
],
“路径”:“somepath2”
]
]

我希望NSOutlineView看起来像上图。

输入数据
let keysDetails:[字符串:任意]=[
“卡多巴格”:[
“locDict”:[
“在”:“添加”,
“ae”:“添加”
],
“jsonDict”:[
“在”:“添加到包中”,
“ae”:“添加到包中”
],
“路径”:“somepath”
],
“kShopTab”:[
“locDict”:[
“be_fr”:“商店”,
“be_nl”:“商店”
],
“jsonDict”:[
“be_fr”:“商店”,
“be_nl”:“商店”
],
“路径”:“somepath2”
]
]
Dictionary是一个无序的集合,当您希望通过索引访问元素时,它会导致问题。。。让我们创建一个自定义结构,它将为
NSOutlineView
提供数据

struct项{
let title:String//第一列值
let loc:String//第二列值
让json:String//第三列值
让子项:[Item]//可能的子项
init(标题:String,loc:String,json:String,子项:[Item]=[]){
self.title=标题
self.loc=loc
self.json=json
self.children=儿童
}
初始化?(标题:字符串,内容:任意){
//检查内容是否为词典,以及是否包含
//locDict和jsonDict都是字典
guard let content=内容为?[字符串:任意],
将loc=content[“locDict”]设为?[String:String],
将json=content[“jsonDict”]设为?[String:String]else{
归零
}
//检查两个字典是否包含相同的键
让locKeys=loc.keys.sorted()
让jsonKeys=json.keys.sorted()
警卫锁具==jsonKeys else{
归零
}
//初始化顶级项
self.title=标题
self.loc=“locDict”
self.json=“jsonDict”
self.children=locKeys.map{输入
//我们可以在这里强制展开,因为我们已经检查过了
//两个字典包含相同的键
项目(标题:key,loc:loc[key]!,json:json[key]!)
}
}
}
这个结构是一个例子,你可以这样做,但有很多其他的 方式。这真的取决于你打算在这里做什么。你可以换 对于对象(而不是结构)

这里的关键点是
children
属性是一个有序集合(数组)

视图控制器 添加
属性(同样,有序集合=数组)

类ViewController:NSViewController{
私人出租项目:[项目]={
//将KeyDetails映射到项目结构的数组
keysDetails.compactMap{(键:字符串,值:任意)在
项目(标题:键,内容:值)
}
}()
}
NSOutlineViewer数据源 顾名思义,数据源只提供数据。我们已经有了
items
属性,让我们使用它

扩展视图控制器:NSOutlineViewDataSource{
func outlineView(outlineView:NSOutlineView,numberOfChildrenOfItem:Any?)->Int{
如果项==nil{
//项目==零
//我们被要求提供顶级元素的数量(kAddToBag,…)
返回项目。计数
}
//开发时间(调试)-检查项目是否真的是项目
断言(项是项);
//项目!=零
//有人问我们一个项目的子项数
返回(项目为!项目).children.count
}
func outlineView(outlineView:NSOutlineView,子索引:Int,of item项:Any?)->Any{
如果项==nil{
//项目==零
//我们需要第n个(索引)顶级元素
退货项目[索引]
}
//开发时间(调试)-检查项目是否真的是项目
断言(项是项);
//项目!=零
//我们需要一个项目的第n个(索引)子项
返回(项为!项)。子项[索引]
}
func大纲视图(outlineView:NSOutlineView,isItemExpandable item:Any)->Bool{
//开发时间(调试)-检查项目是否真的是项目
断言(项是项);
//项只有在有子项时才可展开
返回(项为!项)。children.count>0
}
}
NSOutlineViewDelegate 在其他功能中,委托提供了用于显示特定项的单元格视图 和列

扩展视图控制器:NSOutlineViewDelegate{
func outlineView(outlineView:NSOutlineView,viewFor tableColumn:NSTableColumn?,项目:任意)->NSView{
//获取列标识符和我们的项
guard let columnIdentifier=tableColumn?.identifier,
让项目=项目作为?项目其他{
归零
}
//获取单元格视图标识符和我们应该显示的实际值
让cellViewIdentifier:字符串
让stringValue:String
开关columnIdentifier.rawValue{
案例“标题栏”:
cellViewIdentifier=“标题单元格”
stringValue=item.title
案例“LocColumn”:
cellViewIdentifier=“LocCell”
stringValue=item.loc
案例“JsonColumn”:
cellViewIdentifier=“JsonCell”
stringValue=it