cocoa nstableview动态绑定 - 没有IB

时间:2016-09-20 16:32:49

标签: objective-c cocoa cocoa-bindings

我有一个应用程序需要按组显示大量数据。我在表格的角落视图中放置了一个组选择菜单,允许用户选择要查看的组。

此表的列具有标识符fld#0..n,以及用于获取数据的关联控制器。在目标类中,它将 - 使用IBOutlet绑定到视图控制器检索组选择并使用它来通过切换选择要显示的值。

一切都很花哨,直到我需要支持多个视图/窗口实例。所以我想我会在运行时改变?在表列及其绑定中。到目前为止,我只通过IB做过这样的事情,所以这是我第一次进入内脏并陷入困境。

我的角落视图操作菜单(用户调用的内容):

- (NSMenu *)menuForEvent:(NSEvent *)event
{
    NSMenu * menu = [[[NSMenu alloc] init] autorelease];
    SEL action = @selector(cornerAction:);
    NSMenuItem * item = nil;
    int type = 0;

    //  We auto enable items as views present them
    [menu setAutoenablesItems:YES];

    //  TableView level column customizations
    for (NSString * title in titles)
    {
        BOOL state = dataView.data == type;

        item = [[NSMenuItem alloc] initWithTitle:title
                                          action:action
                                   keyEquivalent:@""];
        [item setRepresentedObject:dataView];
        [item setState:state];
        [item setEnabled:YES];
        [item setTag:type++];
        [item setTarget:dataView];
        [item setAction:action];
        [menu addItem:item];
        [item release];
    }
    return menu;
}

然后采取行动 - 但由于我需要弄清楚如何更新绑定而失败:

- (IBAction)cornerAction:(id)sender
{
    //  Configure which type of data to show, then columns' identifier and sort 
    self.data = (self == sender ? 0 : [sender tag]);

    [super cornerAction:sender];

    for (NSUInteger itm=0; itm<self.fieldCount; itm++)
    {
        NSString * fld = [NSString stringWithFormat:@"fld%@%d", titles[data], itm];
        NSString * key = [NSString stringWithFormat:@"srt%@%d", titles[data], itm];
        NSSortDescriptor * srt = [NSSortDescriptor sortDescriptorWithKey:key ascending:YES];

        [cols[itm] setIdentifier:fld];
        [cols[itm] setSortDescriptorPrototype:srt];

        [cols[itm] bind:<#(nonnull NSString *)#>
               toObject:<#(nonnull id)#>
            withKeyPath:<#(nonnull NSString *)#>
                options:<#(nullable NSDictionary<NSString *,id> *)#>]
    }

    [self reloadArray:YES];
}

cols []是一个表列数组,因此最后一行是将列的绑定更新为控制器(树控制器)到正确数据的起点。我更新了类以删除fld#placesholder列并创建了fld#和srt #ivars的所有变体;这些基本上归还了底层的伊娃。最后,所有访问都是只读的。

我在想我现在需要做的就是更新绑定。我也觉得可能没有必要对标识符和排序描述符进行列更改?

无论如何,我试图避免计划-B,这是采用标签,每组实例化桌面视图 - 哎呀,或者可能有一个更好的方法?

更新:假设我继续计划-A不应该这样做:假设cols [0]的列标识符是fld0

        [cols[itm] bind: @"value"
               toObject: treeController
            withKeyPath: [NSString stringWithFormat:@"arrangedObjects.%@",fld]
                options: nil]

1 个答案:

答案 0 :(得分:0)

由于隐式缓存/对象克隆,最简单的解决方案是实例化表视图。用户界面保持一致,因此没有用户可见的更改,而且是其他类似要求的模型 - 如何通过单个镜头/表视图隐喻查看大量数据。