objective-c - 在 NSTableView 中,如何根据项目的选择对项目进行排序?

标签 objective-c macos cocoa nstableview

我正在使用 Objective-C 开发 macOS 应用程序。我想添加对 NSTableView 进行排序的选项作为一项功能,以在其他项目之前显示所选项目。我的代码是:

NSUInteger idx = [self.itemsTableView.selectedRowIndexes firstIndex];

NSMutableArray *selectedObjects = [NSMutableArray new];

while (idx != NSNotFound)
{
    // do work with "idx"
    // NSLog (@"The current index is %lu", (unsigned long)idx);

    [selectedObjects addObject:self.items[idx]];
    // get the next index in the set
    idx = [self.itemsTableView.selectedRowIndexes indexGreaterThanIndex:idx];
}
self.items = [self.unFilteredItems sortedArrayUsingComparator:^NSComparisonResult(id  _Nonnull obj1, id  _Nonnull obj2) {

        BOOL obj1Exists = [selectedObjects containsObject:obj1];
        BOOL obj2Exists = [selectedObjects containsObject:obj2];


        if (obj1Exists && !obj2Exists) {
            return NSOrderedAscending;
        }
        if (obj1Exists && obj2Exists) {
            return NSOrderedSame;
        }
        if (!obj1Exists && !obj2Exists) {
            return NSOrderedSame;
        }
        if (!obj1Exists && obj2Exists) {
            return NSOrderedDescending;
        }

        return NSOrderedSame;

    }];

    [self.itemsTableView reloadData];

不幸的是,对于大约 70.000 个项目和 4500 个项目的选择,比较器花费了太多时间。有人能给我指出该问题的替代解决方案吗?感谢您的帮助。

编辑:

我现在尝试了另一种解决方案,事实证明该解决方案更快,但仍然不够快:

NSUInteger idx = [self.myMessagesTableView.selectedRowIndexes firstIndex];

NSMutableArray *selectedObjects = [NSMutableArray new];

while (idx != NSNotFound)
{
    // do work with "idx"
    // NSLog (@"The current index is %lu", (unsigned long)idx);

    [selectedObjects addObject:self.myMessages[idx]];
    // get the next index in the set
    idx = [self.myMessagesTableView.selectedRowIndexes indexGreaterThanIndex:idx];
}

NSMutableArray *unselectedObjects = [NSMutableArray new];

[self.unFilteredItems enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

    if (![selectedObjects containsObject:obj]) {
        [unselectedObjects addObject:obj];
    }

}];


self.items = selectedObjects;

self.items = [self.items arrayByAddingObjectsFromArray:unselectedObjects];

[self.itemsTableView reloadData];

我希望有人能给我指出正确的方向,可能尝试使用选择索引而不是选定对象的数组。再次感谢。

最佳答案

如何获取选定的对象并附加未选定的对象

NSArray *selectedObjects = [self.items objectsAtIndexes:self.itemsTableView.selectedRowIndexes];
// invert selectedRowIndexes
NSMutableIndexSet *invertedSelection = [NSMutableIndexSet indexSetWithIndexesInRange:NSMakeRange(0, self.items.count)];
[invertedSelection removeIndexes:self.itemsTableView.selectedRowIndexes];
NSArray *unselectedObjects = [self.items objectsAtIndexes:invertedSelection];
self.items = [selectedObjects arrayByAddingObjectsFromArray:unselectedObjects];
self.itemsTableView.selectedRowIndexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, selectedObjects.count)];
[self.itemsTableView reloadData];

或者删除选定的对象并将它们插入到顶部

NSMutableArray *mutableItems = [self.items mutableCopy];
NSArray *selectedObjects = [self.items objectsAtIndexes:self.itemsTableView.selectedRowIndexes];
[mutableItems removeObjectsAtIndexes:self.itemsTableView.selectedRowIndexes];
NSindexSet *selectedIndexes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, selectedObjects.count)]
[mutableItems insertObjects:selectedObjects atIndexes:selectedIndexes];
self.items = [mutableItems copy];
self.itemsTableView.selectedRowIndexes = selectedIndexes;
[self.itemsTableView reloadData];

我没有测试过这个。

关于objective-c - 在 NSTableView 中,如何根据项目的选择对项目进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53862183/

相关文章:

objective-c - cocoa:有什么方法可以在沙箱中的另一个应用程序中执行粘贴操作

ios - 覆盖对象……这样可以吗?

ruby-on-rails - OS X 10.8 上 Rails 应用程序中的段错误

macos - 更新OS X到El Capitan和Core Plot崩溃:(

macos - 从模板打开无标题文档

ios - 覆盖第一个 iOS 屏幕的简单方法

iphone - 我如何在 iphone 中以相同的方法加载不同的 View

ios - 替代iOS消息传递的“层”消息传递框架

c++ - Qt:如何为两台显示器使用 AA_UseHighDpiPixmaps

xml - NSXMLParser 跳过具有 namespace 的元素