В NSTableView, как сортировать элементы на основе их выбора? - PullRequest
0 голосов
/ 20 декабря 2018

Я разрабатываю приложение macOS в Objective-C.Я хотел бы добавить в качестве функции возможность сортировки 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];

Я надеюсь, что кто-то может указатья в правильном направлении, вероятно, пытаясь использовать индексы выбора вместо массива выбранных объектов.Еще раз спасибо.

Ответы [ 2 ]

0 голосов
/ 20 декабря 2018

Как насчет получения выделенных объектов и добавления невыбранных объектов

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];

Я не проверял это.

0 голосов
/ 20 декабря 2018

Я нашел способ, который на самом деле работает очень быстро, но он не изящен и, конечно, нарушает шаблон MVC, но на данный момент он работает, поэтому любое другое лучшее решение очень приветствуется.Я сейчас использую этот код:

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);
    [self.items[idx] setValue:@YES forKey:@"isItemSelected"];
    [selectedObjects addObject:self.items[idx]];
    // get the next index in the set
    idx = [self.itemsTableView.selectedRowIndexes indexGreaterThanIndex:idx];
}

NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"isItemSelected" ascending:NO];

self.items = [self.unFilteredItems sortedArrayUsingDescriptors:@[descriptor]];


[self.itemsTableView reloadData];

NSMutableIndexSet *set = [[NSMutableIndexSet alloc] init];

NSUInteger a = 0;

for (a=0;a<[selectedObjects count];a++) {

    [set addIndex:a];

}

[self.itemsTableView selectRowIndexes:set byExtendingSelection:NO];

[selectedObjects enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    [obj removeObjectForKey:@"isItemSelected"];
}];

Большое спасибо за ваше внимание.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...