2011-06-06 63 views

回答

4

这取决于你如何填充你的NSTableView。

如果你有一个绑定到一个NSArrayController,又包含您的表视图中显示的项目表视图,然后NSArrayController中有一个选项,以保留选择。您可以从Interface Builder中选择它(或不是)作为NSArrayController的属性。或者你可以在代码中使用setPreservesSelection方法。

不过,如果你完全替代项目的数组NSArrayController的每一个你得到FSEvents时间管理,那么也许选择的保存不能工作。不幸的是,关于NSArrayController的这个属性的Apple文档对于何时可以并且不能保留选择有些含糊。

如果你不使用一个NSArrayController,但也许用一个数据源来填充表视图,那么我认为你必须自己管理的选择。

+0

感谢您的解释。我真的想用一个NSArrayController – 2011-06-09 05:59:19

+2

我发现setPreservesSelection是非常不可靠的。有时它起作用,有时它不起作用。 – 2012-09-11 15:34:02

9

那么,你可以在调用reloadData之前保存选择并在之后恢复。

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

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

3

@ 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]; 
} 
+0

布拉德,你试过这个吗? reloadData被延迟加载,所以你在调用之后不会有更新的数据。要在拖动/移动操作之后测试这个代码,这会改变行的顺序。我不认为它会产生预期的结果。 – 2017-01-25 18:11:56

+0

@SteveSheldon我记得这个工作,但不幸的是这个项目不再运行,所以我不能再测试了。 – 2017-03-03 15:28:16

+0

@SteveSheldon,我认为这有效;我使用了类似的技术;如果我记得,苹果的文档甚至提到这一点。你指的是哪些更新的数据?之后打电话? – Jerry 2017-05-02 07:13:02

3

在上reloadData()使用数据源,苹果文档在头文件的情况下是

所选行不保持。

为了解决问题,您可以使用reloadDataForRowIndexes(rowIndexes: NSIndexSet, columnIndexes: NSIndexSet)。正如在同一头文件中提到的那样

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

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

4

[夫特3]

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

extension NSTableView { 

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

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

+0

小记事,这将选择第一个和上一个选定的项目,如果您只想要先前选择的项目,将“byExtendingSelection”设置为false – 2017-01-12 21:59:29