我有一个NSTableView,它通过NSArrayController绑定到NSMutableArray。数组中的内容是派生类;表的前几列绑定到基类上存在的属性。一切正常。
我遇到问题的地方是一个列,只有当行映射到一个特定的子类时才应填充该列。该列要显示的属性仅存在于该子类中,因为它对基类没有意义。用户将从前两列了解为什么第三列的单元格已填充/可编辑。
第三列的值绑定在arrangeObjects上,模型路径类似于“foo.name”,其中foo是子类的属性。但是,这不起作用,因为层次结构中的其他子类与foo不符合键值。
似乎我唯一的选择是让foo成为基类的属性,这样每个人都会响应它,但这会使模型对象的接口变得混乱。
有没有人为这种情况想出一个干净的设计?它不是不常见的(我是Cocoa的相对新人,我只是在学习绑定的来龙去脉。)
答案 0 :(得分:1)
解决此问题的一种方法是仅对其工作的前两列使用绑定。对于其余列,您实现了一个NSTableViewDataSource,它实现了所需的自定义逻辑。
首先创建一个实现
的新类-tableView:objectValueForTableColumn:row:
-tableView:setObjectValue:forTableColumn:row:
(如果用户应该编辑其他列,则只需要第二个)。然后添加
IBOutlet NSArrayController *valuesController;
该类的实例变量。
在Interface Builder内部添加该类的新对象(将蓝色“对象”立方体从库中拖到文件的窗口中)。将阵列控制器连接到新数据源。然后将数据源与表视图连接,使其成为表视图的数据源。
确保前两个列没有绑定任何内容。
在
-tableView:objectValueForTableColumn:row:
方法将根据需要调用这些列,您可以根据需要查看对象:
- (id)tableView:(NSTableView *)aTableView
objectValueForTableColumn:(NSTableColumn *)aTableColumn
row:(NSInteger)rowIndex;
{
NSObject *myObject = [[valuesController arrangedObjects] objectAtIndex:rowIndex];
id columnIdentifier = [aTableColumn identifier];
if ([columnIdentifier isEqual:@"foo"]) {
if ([myObject respondsToSelector:@selector(fooValue)]) {
return [myObject fooValue];
}
}
return nil;
}
请注意我是如何使用列标识符来查看正在请求的列。在Interface Builder中设置列标识符。