19

我有一个NSTableView显示目录的内容。我关注 FSEvents,每次收到事件时,我都会重新加载我的表格视图。不幸的是,当前选择随即消失。有没有办法避免这种情况?

4

5 回答 5

11

好吧,您可以在调用 reloadData 之前保存选择并在之后恢复它。

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

在某些情况下,这对我有用。但是,如果您在所选行之前插入一些项目,您应该通过向其中添加已添加项目的计数来调整您的行变量。

于 2012-11-29T10:38:25.977 回答
11

斯威夫特 4.2

创建一个扩展并添加一个保留选择的方法。

extension NSTableView {

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

如果您使用填充表格视图的传统方式(不是 NSArrayController),请执行此操作。

于 2016-12-28T16:52:23.250 回答
6

在使用数据源的情况下,头文件中的Apple DocumentationreloadData()

不维护选定的行。

要绕过,您可以使用reloadDataForRowIndexes(rowIndexes: NSIndexSet, columnIndexes: NSIndexSet). 如同一头文件中所述

对于可见的单元格,将调用适当的 dataSource 和委托方法并重新绘制单元格。

因此数据将被重新加载,并且选择也被保留。

于 2016-02-19T07:44:52.340 回答
5

这取决于您如何填充 NSTableView。

如果您将表格视图绑定到 NSArrayController,而后者又包含您的表格视图正在显示的项目,那么 NSArrayController 可以选择保留选择。您可以从 Interface Builder 中选择(或不选择)它作为 NSArrayController 上的属性。或者您可以setPreservesSelection在代码中使用该方法。

但是,如果您在每次获取 FSEvents 时完全替换 NSArrayController 管理的项目数组,那么可能无法保存选择。不幸的是,关于 NSArrayController 的此属性的 Apple 文档对于何时可以保留选择以及何时不能保留选择有点模糊。

如果您没有使用 NSArrayController,但可能使用数据源来填充表格视图,那么我认为您必须自己管理选择。

于 2011-06-09T00:46:10.957 回答
4

@silvansky 答案的变体。

这个不需要跟踪插入/删除的项目数。并且它保持多项选择。

这个想法是...
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];
}
于 2015-04-22T00:28:07.707 回答