Macos 将基于视图的NSOutlineView绑定到核心数据
我正试图在我的Mac应用程序中实现新的基于视图的大纲视图作为源列表。但是,我无法显示值,因此我从核心数据应用程序模板制作了一个小型测试应用程序,也无法在其中正常工作 我在数据模型中定义了两个简单的类;让我们称他们为“父母”和“孩子”Parent只有一个属性“name”,一个关系“children”name是可选字符串,children是与Child的许多关系的可选字符串Child具有相同的“name”属性和与children相反的对一“parent”关系。我为这两个类生成了自定义类,并在Child中为children编写了一个存根,返回Macos 将基于视图的NSOutlineView绑定到核心数据,macos,cocoa,nstableview,osx-lion,nsoutlineview,Macos,Cocoa,Nstableview,Osx Lion,Nsoutlineview,我正试图在我的Mac应用程序中实现新的基于视图的大纲视图作为源列表。但是,我无法显示值,因此我从核心数据应用程序模板制作了一个小型测试应用程序,也无法在其中正常工作 我在数据模型中定义了两个简单的类;让我们称他们为“父母”和“孩子”Parent只有一个属性“name”,一个关系“children”name是可选字符串,children是与Child的许多关系的可选字符串Child具有相同的“name”属性和与children相反的对一“parent”关系。我为这两个类生成了自定义类,并在Chil
nil
我将一个源列表从对象库拖到我的XIB上,并放入一个树控制器中。树控制器的子项关键路径设置为“子项”,它处于实体名称模式,以“父项”作为实体名称,准备选中的内容,并将其托管对象上下文设置为应用程序代理的上下文。树控制器是outline视图的数据源,我使用“objectValue.name”键路径将数据单元的文本视图绑定到表单元视图
在-applicationdFinishLaunching:
中,我创建了两个父实例,一个具有子实例,并为每个对象指定名称属性
实际问题
现在,通过这种设置,我可以在源代码列表中看到行,但是文本字段是空的,即使它们是绑定的。我认为我不需要做任何其他事情,因为我使用的是绑定,而且我相当确定绑定到objectValue
属性是正确的。怎么了
如果需要的话,我可以提供更多的细节,但我很确定这涵盖了我所做的一切。哇,就像两周前我问这个问题一样 不管怎样,如果你和我一样,问题是,
对于基于视图的
NSOutlineViews
,您需要实现
- (NSView *)outlineView:(NSOutlineView *)outlineView
viewForTableColumn:(NSTableColumn *)tableColumn
item:(id)item;
委派方法并返回您设置的NSTableCellView
,否则他们只会给你一个空行。最简单的方法就是打电话
[outlineView makeViewWithIdentifier:@"MyCell" owner:self]
将MyCell
替换为您键入的任何内容作为“用户界面项标识符”在您的
NSTableCellView
的身份检查器中
目标C:
斯威夫特:
更新2018-08-02:
实际上,您不需要设置委托。下面是我如何让它工作的(使用NSTreeController
进行测试,但也应该使用NSArrayController
):
- 将每个列对象绑定到排列对象(不带模型键路径)
- 将最内部的自定义视图(例如标签字段)绑定到
objectValue.yourCustomValue
- 应该没有必要,但如果这不起作用,请尝试为列和
设置标识符。确保两个标识符相同。对具有不同标识符的其余列重复该操作TableCellView
屏幕截图:如上所述,您需要实现委托方法来返回视图 考虑到我在文档中找不到这种方法,这真是一个谜 关于
(id)项
参数的类型,它是NSTreeControllerTreeNode
,它是NSTreeNode
的一个未记录的子类。如果对其进行强制转换,则可以获取单元的对象,并根据对象的类型或该对象的任何属性返回不同的视图,以确定单元视图类型:
- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
NSTableCellView *view = nil;
NSTreeNode *node = item;
if ([node.representedObject isKindOfClass:[Group class]]) {
view = [outlineView makeViewWithIdentifier:@"HeaderCell" owner:self];
} else {
view = [outlineView makeViewWithIdentifier:@"DataCell" owner:self];
}
return view;
}
这似乎是对Xcode 4或其附近的更改。Interface builder在NSOutlineView下添加两个NSTableCellView对象。如果删除NSTableCellView对象,您将返回到一个更健全(或至少有文档记录)的世界,在那里您需要实现以下方法:
outlineView:dataCellForTableColumn:item
outlineView:willDisplayCell:forTableColumn:item
…或者,如果您想查看源列表,至少您可以这样做。在任何情况下,这就是SourceView示例的设置方式,也是为什么在尝试重新创建SourceView示例时会遇到如此混乱的情况
或者,如果要继续使用NSTableCellView对象(非常有用),则可以:
- 将NSOutlineView“内容”绑定到TreeController.arrangedObjects
- 使用objectValue的模型键路径将NSTableCellView下的NSTextField(和/或NSImageView)绑定到“表单元格视图”。
NSOutlineView
进行populplates,而不是使用CoreData,但关键因素是,如@boaz Stuler所述,选择了正确的单元格(类似于您在iOS中处理UITableViewCell
的方式)
因此,在中,我实现了如下方法:
- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
if ([self isHeader:item]) {
return [outlineView makeViewWithIdentifier:@"HeaderCell" owner:self];
} else {
return [outlineView makeViewWithIdentifier:@"DataCell" owner:self];
}
}
查看github。
大部分内容要么在IB中完成,要么可以在
除了使用绑定之外,还需要实现此功能。绑定仍然可以处理设置单元格视图的objectValue,以及将单元格视图的子视图绑定到该objectValue。但是仍然需要此方法来告诉outline视图对特定行/列使用哪个单元格视图。这是必要的,因为源列表使用默认情况下,同一列中有两个不同的单元格,HeaderCell和DataCell,它不能为您选择一个单元格,就像您只有一个单元格并且其标识符设置为自动一样。感谢这个答案!我几乎放弃了搜索。但我有以下问题:当我设置标识符时,方法
-大纲视图:viewForTableColumn:item:
永远不会被调用。当我没有设置标识符时-outlineView:objec
- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
NSTableCellView *view = nil;
NSTreeNode *node = item;
if ([node.representedObject isKindOfClass:[Group class]]) {
view = [outlineView makeViewWithIdentifier:@"HeaderCell" owner:self];
} else {
view = [outlineView makeViewWithIdentifier:@"DataCell" owner:self];
}
return view;
}
- (NSView *)outlineView:(NSOutlineView *)outlineView viewForTableColumn:(NSTableColumn *)tableColumn item:(id)item {
if ([self isHeader:item]) {
return [outlineView makeViewWithIdentifier:@"HeaderCell" owner:self];
} else {
return [outlineView makeViewWithIdentifier:@"DataCell" owner:self];
}
}