NSTableView 排序绑定 - 编程解决方案

NSTableView sort bindings - programatic Solution

First-time 网站上的提问者。我一直在尝试通过将绑定从故事板中取出并尝试在代码中重现效果来了解更多关于 NSTableView 绑定与 NSArrayController 的关系。我可以使用绑定配置 NSTableView 和 NSArrayController 的初始排序顺序,但我似乎仍然无法在单击列时对它们进行排序。

背景是我有一个标准,cell-based 故事板中的 NSTableView 通过 IBOutlet 绑定到 NSViewController。 NSViewController 具有以下 viewDidLoad 方法:

- (void)viewDidLoad
{
    [super viewDidLoad];

    //setup the array controller
    self.arrayController = [NSArrayController new];
    [self.arrayController addObject:@{@"namef": @"Test1", @"namel": @"a"}];
    [self.arrayController addObject:@{@"namef": @"Test2", @"namel": @"b"}];
    [self.arrayController addObject:@{@"namef": @"Test3", @"namel": @"c"}];
    [self.arrayController addObject:@{@"namef": @"Test4", @"namel": @"B"}];

    //setup the table view column bindings and sorting
    [[self.tableView tableColumnWithIdentifier:@"0"] bind:NSValueBinding toObject:self.arrayController withKeyPath:@"arrangedObjects.namef" options:nil];
    [[self.tableView tableColumnWithIdentifier:@"0"] setSortDescriptorPrototype:[NSSortDescriptor sortDescriptorWithKey:@"namef" ascending:YES selector:@selector(caseInsensitiveCompare:)]];

    [[self.tableView tableColumnWithIdentifier:@"1"] bind:NSValueBinding toObject:self.arrayController withKeyPath:@"arrangedObjects.namel" options:nil];
    [[self.tableView tableColumnWithIdentifier:@"1"] setSortDescriptorPrototype:[NSSortDescriptor sortDescriptorWithKey:@"namel" ascending:YES selector:@selector(caseInsensitiveCompare:)]];

    //Bind the array controller to the tableView
    [self.tableView bind:NSContentBinding toObject:self.arrayController withKeyPath:@"arrangedObjects" options:nil];
    [self.tableView bind:NSSelectionIndexesBinding toObject:self.arrayController withKeyPath:@"selectionIndexes" options:nil];

    //setup sorting
    [self.tableView setSortDescriptors:[NSArray arrayWithObject: [[NSSortDescriptor alloc] initWithKey:@"namel" ascending:YES selector:@selector(caseInsensitiveCompare:)]]];
    [self.arrayController bind:NSSortDescriptorsBinding toObject:self withKeyPath:@"sortDescriptors" options:nil];
    [self.arrayController setAutomaticallyRearrangesObjects:YES];
}

这会导致成功加载屏幕,其中 table 视图按 "namel" 数据排序,每列 header 显示为可点击,箭头指向 up/down每次点击。

但是,排序顺序没有改变...

阅读其他各种文章和 Whosebug 问题,我看到了 "you just need to bind the columns to the array controller and the NSTableView will auto-bind itself" 之类的答案以及经常涉及故事板的各种其他解释。

我已经尝试了多种注释掉以下代码组件的组合。我试过更改每列中 sortDescriptorPrototypes 内的文本。

我知道我遗漏了一条重要线索,而且有关这方面的文档非常糟糕。谁能看到我做错了什么?我如何让它正确绑定,以便单击 headers 列实际对数据进行排序?

所以这些事情很常见,我自己找到了答案。所以对于那些后来的人,请阅读以下内容:

我的问题是我在 NSArrayController 和 NSTableView 之间连接了太多绑定。我问题中的绑定是:

a) 2 table-视图列将它们的值绑定到数组控制器的内容

b) table-view 也将其内容绑定到数组控制器

c) table-视图将其选择索引绑定到数组控制器

d) 数组控制器将其排序描述符绑定到 table-视图排序描述符的本地引用。

我删除了绑定 b 和 c,一切都开始工作了。我以为我以前尝试过,但是当我尝试它时一定有一个额外的错误。下面是我的 viewDidLoad 方法的功能副本:

- (void)viewDidLoad
{
    [super viewDidLoad];

    //setup the array controller
    self.arrayController = [NSArrayController new];

    [self.arrayController addObject:@{@"namef": @"Test1", @"namel": @"a"}];
    [self.arrayController addObject:@{@"namef": @"Test2", @"namel": @"b"}];
    [self.arrayController addObject:@{@"namef": @"Test3", @"namel": @"c"}];
    [self.arrayController addObject:@{@"namef": @"Test4", @"namel": @"B"}];

    //setup the table view
    [[self.tableView tableColumnWithIdentifier:@"0"] bind:NSValueBinding toObject:self.arrayController withKeyPath:@"arrangedObjects.namef" options:nil];
    [[self.tableView tableColumnWithIdentifier:@"0"] setSortDescriptorPrototype:[NSSortDescriptor sortDescriptorWithKey:@"namef" ascending:YES selector:@selector(caseInsensitiveCompare:)]];

    [[self.tableView tableColumnWithIdentifier:@"1"] bind:NSValueBinding toObject:self.arrayController withKeyPath:@"arrangedObjects.namel" options:nil];
    [[self.tableView tableColumnWithIdentifier:@"1"] setSortDescriptorPrototype:[NSSortDescriptor sortDescriptorWithKey:@"namel" ascending:YES selector:@selector(caseInsensitiveCompare:)]];

    //setup sorting
    [self.tableView setSortDescriptors:[NSArray arrayWithObject: [[NSSortDescriptor alloc] initWithKey:@"namel" ascending:YES selector:@selector(caseInsensitiveCompare:)]]];
    [self.arrayController bind:NSSortDescriptorsBinding toObject:self.tableView withKeyPath:@"sortDescriptors" options:nil];
    [self.arrayController setAutomaticallyRearrangesObjects:YES];

}