在NSTableView中重新加载数据,但保持当前选择

AP.*_*AP. 17 macos cocoa objective-c nstableview fsevents

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

sil*_*sky 10

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

NSInteger row = [self.tableView selectedRow];
[self.tableView reloadData];
[self.tableView selectRowIndexes:[NSIndexSet indexSetWithIndex:row] byExtendingSelection:NO];
Run Code Online (Sandbox Code Playgroud)

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


tes*_*sla 9

Swift 4.2

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

extension NSTableView {

    func reloadDataKeepingSelection() {
        let selectedRowIndexes = self.selectedRowIndexes
        self.reloadData()
        self.selectRowIndexes(selectedRowIndexes, byExtendingSelection: true)
    }
}
Run Code Online (Sandbox Code Playgroud)

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


Har*_* Ng 6

在使用数据源的情况下,头文件中的Apple文档reloadData()就是这样

不维护选定的行.

四处走走,你可以使用reloadDataForRowIndexes(rowIndexes: NSIndexSet, columnIndexes: NSIndexSet).正如在同一个头文件中提到的那样

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

因此,将重新加载数据,并保留选择.


OzB*_*dit 5

这取决于您如何填充NSTableView.

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

但是,如果您在每次获得FSEvent时完全替换NSArrayController管理的项目数组,那么保留选择可能无法正常工作.不幸的是,关于NSArrayController的这个属性的Apple文档在何时可以并且不能保留选择方面有点模糊.

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

  • 我发现setPreservesSelection非常不可靠.有时候它有效,有时则不然. (2认同)