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