我有一个NSTableView
显示目录的内容。我注意FSEvents,每次我得到一个事件我重新加载我的表视图。 不幸的是,当前的选择然后消失。有没有办法避免这种情况?reloadData在NSTableView,但保持当前选择
回答
这取决于你如何填充你的NSTableView。
如果你有一个绑定到一个NSArrayController,又包含您的表视图中显示的项目表视图,然后NSArrayController中有一个选项,以保留选择。您可以从Interface Builder中选择它(或不是)作为NSArrayController的属性。或者你可以在代码中使用setPreservesSelection方法。
不过,如果你完全替代项目的数组NSArrayController的每一个你得到FSEvents时间管理,那么也许选择的保存不能工作。不幸的是,关于NSArrayController的这个属性的Apple文档对于何时可以并且不能保留选择有些含糊。
如果你不使用一个NSArrayController,但也许用一个数据源来填充表视图,那么我认为你必须自己管理的选择。
那么,你可以在调用reloadData之前保存选择并在之后恢复。
NSInteger row = [self.tableView selectedRow];
[self.tableView reloadData];
[self.tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
这在某些情况下适用于我。但是,如果在选定行之前插入一些项目,则应该通过向其添加项目的计数来调整行变量。
@ 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];
}
布拉德,你试过这个吗? reloadData被延迟加载,所以你在调用之后不会有更新的数据。要在拖动/移动操作之后测试这个代码,这会改变行的顺序。我不认为它会产生预期的结果。 – 2017-01-25 18:11:56
@SteveSheldon我记得这个工作,但不幸的是这个项目不再运行,所以我不能再测试了。 – 2017-03-03 15:28:16
@SteveSheldon,我认为这有效;我使用了类似的技术;如果我记得,苹果的文档甚至提到这一点。你指的是哪些更新的数据?之后打电话? – Jerry 2017-05-02 07:13:02
在上reloadData()
使用数据源,苹果文档在头文件的情况下是
所选行不保持。
为了解决问题,您可以使用reloadDataForRowIndexes(rowIndexes: NSIndexSet, columnIndexes: NSIndexSet)
。正如在同一头文件中提到的那样
对于可见的单元格,将调用适当的dataSource和委托方法,并重绘单元格。
因此,数据将被重新加载,并且选择也被保留。
[夫特3]
创建扩展并添加其保留选择的方法。
extension NSTableView {
func reloadDataKeepingSelection() {
let selectedRowIndexes = self.selectedRowIndexes
self.reloadData()
self.selectRowIndexes(selectedRowIndexes, byExtendingSelection: true)
}
}
如果您使用传统方式填充表视图(而不是NSArrayController),请执行此操作。
小记事,这将选择第一个和上一个选定的项目,如果您只想要先前选择的项目,将“byExtendingSelection”设置为false – 2017-01-12 21:59:29
- 1. 如何更新选择的选项,但保持先前选择的选项?
- 2. NSTableView reloadData泄漏内存
- 3. 保持选择
- 4. 选择后保持焦点选择2
- 5. PHP:选择当前选项
- 6. 滚动NSTableView的选择到
- 7. NSTableView - 禁用行选择
- 8. NSTableView的选择和亮点
- 9. swiperjs - 如何保持prev和next滑块在眼前,但不居中当前
- 10. 保持图像选择
- 11. Laravel保持选择的值
- 12. 变化Selectize选择,但保留先前选定值
- 13. 如何使用ddaccordian.init保持当前类别选项卡保持打开状态?
- 14. 无法获取的DatePicker选择当前日期(ANDROID),保持上月启用
- 15. Extjs保持组合中的当前选择项并添加新项目
- 16. 需要popviewcontroller,但保持当前视图隐藏
- 17. 启动多个新窗口,但保持当前视图有效
- 18. 通过reloadData更新UITableView时保留选择
- 19. 无法在NSTableView中进行空选择
- 20. 在NSTableView和NSOutlineView之间选择
- 21. 在当前dom前添加dom,并保持当前dom停留在视口中
- 22. 保持选择的细胞在夫特
- 23. 选择当前元素
- 24. XSL:选择当前节点
- 25. 当前时间选择器
- 26. 选择当前链接
- 27. Crystal Reports - 选择当前YYMM
- 28. 当tableView reloadData
- 29. 如何保持uikit.sticky保持在最前
- 30. Laravel如何保持选择选项
感谢您的解释。我真的想用一个NSArrayController – 2011-06-09 05:59:19
我发现setPreservesSelection是非常不可靠的。有时它起作用,有时它不起作用。 – 2012-09-11 15:34:02