设置和维护NSTableView的第一个SortDescriptor

时间:2011-12-06 13:51:02

标签: cocoa nstableview cocoa-bindings nsarraycontroller nssortdescriptor

我有一个NSTableView,其列绑定到NSArrayController

表格视图显示电子邮件列表:

  • 未读标记
  • 主题
  • 附件尺寸

用户可以单击“附件大小”列对列表进行排序,但我希望表始终按“未读”标记排序,以便未读消息始终保留在列表的顶部。

我没有将Array Controller的排序描述符绑定到任何东西,但是表格排序通过单击表格列神奇地工作(为什么?)。有没有什么方法可以拦截设置数组控制器的排序描述符并首先插入“未读”排序描述符?

按附件大小排序的表格示例:

UNREAD▼ SUBJECT ATTACHMENT SIZE▼
------  ------- ------------------
  yes   Hello.. 110kb
  yes   Test...  90kb

  no    Foobar  200kb
  no    Hey     100kb
  no    Test2    10kb

2 个答案:

答案 0 :(得分:0)

嗯,它“正常工作”的原因是因为表格列在其绑定的NSArrayController上调用setSortDescriptors:

假设您希望表格保持可排序状态,但您总是希望按“未读”排序,这就是我要做的事情:

首先,子类NSArrayController并覆盖arrangeObjects

- (NSArray *)arrangeObjects:(NSArray *)objects {

    NSMutableArray *oldSorted = [[super arrangeObjects:objects] mutableCopy];
    NSMutableArray *newSorted = [NSMutableArray arrayWithCapacity:[oldSorted count]];

    for (id anObject in oldSorted)
        if ([[anObject valueForKey:@"isUnread"] boolValue])
            [newSorted addObject:anObject];

    [oldSorted removeObjectsInArray:newSorted];
    [newSorted addObjectsFromArray:oldSorted];
    [oldSorted release];

    return newSorted;
}

这会将未读消息放在“顶部”(数组的开头)。我不确定这是最有效的排序算法,但我相信这是正确的方法。

答案 1 :(得分:0)

我认为您可以在awakeFromNib期间在阵列控制器上设置sortDescriptors数组。无需强制arrangeObjects:,此功能完全内置。

- (void)awakeFromNib {
    [super awakeFromNib];
    NSSortDescriptor *unreadSorter = [[NSSortDescriptor sortDescriptorWithKey:@"isUnread" ascending:NO)] autorelease];
    NSArray *arrayOfSortDescriptors = [NSArray arrayWithObject:unreadSorter];
    [self setSortDescriptors:arrayOfSortDescriptors];
}

单击列标题时,列仍将保持可排序状态。