我有一个NSTableView
显示目录的内容。我关注 FSEvents,每次收到事件时,我都会重新加载我的表格视图。不幸的是,当前选择随即消失。有没有办法避免这种情况?
5 回答
好吧,您可以在调用 reloadData 之前保存选择并在之后恢复它。
NSInteger row = [self.tableView selectedRow];
[self.tableView reloadData];
[self.tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
在某些情况下,这对我有用。但是,如果您在所选行之前插入一些项目,您应该通过向其中添加已添加项目的计数来调整您的行变量。
斯威夫特 4.2
创建一个扩展并添加一个保留选择的方法。
extension NSTableView {
func reloadDataKeepingSelection() {
let selectedRowIndexes = self.selectedRowIndexes
self.reloadData()
self.selectRowIndexes(selectedRowIndexes, byExtendingSelection: false)
}
}
如果您使用填充表格视图的传统方式(不是 NSArrayController),请执行此操作。
在使用数据源的情况下,头文件中的Apple DocumentationreloadData()
是
不维护选定的行。
要绕过,您可以使用reloadDataForRowIndexes(rowIndexes: NSIndexSet, columnIndexes: NSIndexSet)
. 如同一头文件中所述
对于可见的单元格,将调用适当的 dataSource 和委托方法并重新绘制单元格。
因此数据将被重新加载,并且选择也被保留。
这取决于您如何填充 NSTableView。
如果您将表格视图绑定到 NSArrayController,而后者又包含您的表格视图正在显示的项目,那么 NSArrayController 可以选择保留选择。您可以从 Interface Builder 中选择(或不选择)它作为 NSArrayController 上的属性。或者您可以setPreservesSelection
在代码中使用该方法。
但是,如果您在每次获取 FSEvents 时完全替换 NSArrayController 管理的项目数组,那么可能无法保存选择。不幸的是,关于 NSArrayController 的此属性的 Apple 文档对于何时可以保留选择以及何时不能保留选择有点模糊。
如果您没有使用 NSArrayController,但可能使用数据源来填充表格视图,那么我认为您必须自己管理选择。
@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];
}