以编程方式将列(带有绑定)添加到基于视图的NSTableView?

时间:2013-08-30 22:19:06

标签: cocoa nstableview cocoa-bindings nstablecolumn

我有一个简单的应用程序,列出NSTableView中的一些模型。

该表是一个完全标准的基于视图的表,包含几列,并通过NSArrayController使用绑定填充。所有这些都是在Interface Builder中设置的,它可以正常工作。

现在,我想以编程方式添加更多列,并将这些新列绑定到模型中的各种键路径。在那里,我被困住了。

为简单起见,假设这个设置:

  1. Model对象是只有一个NSString属性的普通对象:name
  2. AppDelegate有一个NSArray属性(models),它包含许多模型实例。
  3. NSArrayController的content绑定到应用程序委托的models数组。
  4. NSTableView的content绑定到阵列控制器的arrangedObjects
  5. 表的第一列被绑定(在IB中)以显示name属性,即列→表格单元格视图→静态文本表格视图单元格→绑定到表格单元格查看 objectValue.name
  6. 就我所知,这是直截了当的,并且通过这本书,它就像一个魅力。

    但是...... 如何添加更多列呢?

    要以编程方式添加列(为了简单起见,我们只是说这个新列应该只显示name属性,就像已经存在的列一样),我想我会在app delegate中做这样的事情:

    NSTableColumn* newColumn = [[NSTableColumn alloc] initWithIdentifier:@"newColumn"];
    
    // do binding magic somehow
    // [[newColumn dataCell] bind:NSValueBinding toObject:??? withKeyPath:??? options:nil];
    
    [self.table addColumn:newColumn]; // the table's connected with an IBOutlet
    

    我已经尝试了很多来自/与数据单元,表,列,数组控制器,数组本身以及各种键路径的绑定组合,但没有任何作用。新列添加得很好,但它从未填充过。

    我想我创建的基本NSTableColumn实例是基于单元格的,而不是基于视图的,这会造成麻烦。但是,我不知道如何从这里开始,文档从不谈论以编程方式添加的绑定列。

    在这种情况下,我想要的只是一个简单的文本列,绑定到模型,就像我可以轻松设置IB的那样。

    我可以通过实现NSTableViewDataSource和“手动”输入表来完成所有这些操作,但我已经使用绑定设置了其他所有内容。

    非常感谢任何帮助。

2 个答案:

答案 0 :(得分:6)

试试这样: -

NSString *akey = @"keyValue";
NSString *keypath = [NSString stringWithFormat:@"arrangedObjects.%@",akey];
NSTableColumn *tableColumn=[[NSTableColumn alloc]initWithIdentifier:@"newColumn"];

[tableView addTableColumn:tableColumn];
[tableColumn bind:NSValueBinding toObject:yourArrayController withKeyPath:keypath options:nil];
NSMutableDictionary *dc=[NSMutableDictionary dictionary];
[dc setObject:@"textValue" forKey:@"keyValue"];
[yourmutableArray addObject:dc];
[self setYourmutableArray:yourmutableArray];

请注意: - 您的可变数组应绑定到arraycontroller,然后才会填充数据

答案 1 :(得分:2)

您需要使用此委托方法绑定到列的NSTableCellView的子视图:

- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row
{
    // Get cell view - NSTableCellView
    // This can be a prototype loaded from the table view or from another nib
    // see : - registerNib:forIdentifier:
    NSView *cellView = [tableView makeViewWithIdentifier:@"Cell1" owner:[tableView delegate]];

    // - subViewWithIdentifier is a simple category method that searches -subviews
    NSView *subView = [cellView subViewWithIdentifier:@"TextField1"];
    [subView bind: NSValueBinding toObject:cellView withKeyPath: @"objectValue.name" options: nil];

    subView = [cellView subViewWithIdentifier:@"TextField2"];
    [subView bind: NSValueBinding toObject:cellView withKeyPath: @"objectValue.address" options: nil];

    return cellView;
}

NSView类别方法:

- (NSView *)subViewWithIdentifier:(NSString *)theIdentifier
{
    __block NSView *subView = nil;
    [[self subviews] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
#pragma unused(idx)
        if ([[obj identifier] isEqualToString:theIdentifier]) {
            subView = obj;
            *stop = YES;
        }
    }];
    return subView;
}