reloadData в NSTableView, но сохранить текущий выбор - PullRequest
16 голосов
/ 06 июня 2011

У меня есть NSTableView, показывающий содержимое каталога. Я наблюдаю за FSEvents, и каждый раз, когда я получаю событие, я перезагружаю свое табличное представление. К сожалению, текущий выбор исчезает. Есть ли способ избежать этого?

Ответы [ 5 ]

10 голосов
/ 29 ноября 2012

Ну, вы можете сохранить выделение перед вызовом reloadData и восстановить его после этого.

NSInteger row = [self.tableView selectedRow];
[self.tableView reloadData];
[self.tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];

В некоторых случаях это работало для меня.Но если вы вставляете некоторые элементы ДО выбранной строки, вам следует просто изменить переменную строки, добавив к ней количество добавленных элементов.

7 голосов
/ 28 декабря 2016

Swift 4.2

Создайте расширение и добавьте метод, который сохраняет выбор.

extension NSTableView {

    func reloadDataKeepingSelection() {
        let selectedRowIndexes = self.selectedRowIndexes
        self.reloadData()
        self.selectRowIndexes(selectedRowIndexes, byExtendingSelection: true)
    }
}

Сделайте это в случае, если вы используете традиционный способ заполнения табличных представлений (не NSArrayController).

5 голосов
/ 19 февраля 2016

В случае использования источника данных документация Apple в файле заголовка на reloadData() означает, что

Выбранные строки не поддерживаются.

Чтобы обойти, вы можете использовать reloadDataForRowIndexes(rowIndexes: NSIndexSet, columnIndexes: NSIndexSet). Как уже упоминалось в том же заголовочном файле

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

Таким образом, данные будут перезагружены, и выбор также сохраняется.

5 голосов
/ 09 июня 2011

Это зависит от того, как вы заполняете свой NSTableView.

Если у вас табличное представление, привязанное к NSArrayController, который, в свою очередь, содержит элементы, которые отображает ваше табличное представление, то NSArrayController имеет возможность сохранитьвыбор.Вы можете выбрать его (или нет) в Интерфейсном Разработчике как свойство NSArrayController.Или вы можете использовать метод setPreservesSelection в коде.

Однако, если вы полностью замените массив элементов, которыми NSArrayController управляет каждый раз, когда вы получаете ваши FSEvents, то, возможно, сохранение выбора не сработает.К сожалению, документы Apple по этому свойству NSArrayController немного расплывчаты относительно того, когда он может и не может сохранить выделение.

Если вы не используете NSArrayController, но, возможно, используете dataSource для заполнения табличного представления, тогдаЯ думаю, что вам придется управлять выбором самостоятельно.

4 голосов
/ 22 апреля 2015

Вариант ответа Сильванского.

В этом нет необходимости отслеживать количество вставленных / удаленных элементов. И он поддерживает множественный выбор.

Идея состоит в том, чтобы ...
1. создать массив выбранных объектов / узлов из текущего выделения.
2. обновить таблицу, используя reloadData
3. для каждого объекта, полученного на шаге 1, найдите / запишите его новый индекс
4. скажите табличному виду / схематическому виду выбрать обновленный набор индексов

- (void)refresh {
    // initialize some variables
    NSIndexSet *selectedIndexes = [self.outlineView selectedRowIndexes];
    NSMutableArray *selectedNodes = [NSMutableArray array];
    NSMutableIndexSet *updatedSelectedIndex = [NSMutableIndexSet indexSet];

    // 1. enumerate all selected indexes and record the nodes/objects
    [selectedIndexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
        [selectedNodes addObject:[self.outlineView itemAtRow:idx]];
    }];

    // 2. refresh the table which may add new objects/nodes
    [self.outlineView reloadData];

    // 3. for each node in step 1, find the new indexes
    for (id selectedNode in selectedNodes) {
        [updatedSelectedIndex addIndex:[self.outlineView rowForItem:selectedNode]];
    }

    // 4. tell the outline view to select the updated index set
    [self.outlineView selectRowIndexes:updatedSelectedIndex byExtendingSelection:NO];
}
...