Swift 对绑定到NSArrayController的NSTableview表进行排序后,所选行不再与数组元素匹配

Swift 对绑定到NSArrayController的NSTableview表进行排序后,所选行不再与数组元素匹配,swift,Swift,我在IB中对表设置了Double Action,当我在对表排序后双击tableview行时,tableview.selectedRow现在与最初加载它的数组的索引不同 let trade=trades[tableView.selectedRow]让我查看trade.tradeNo和其他模型元素,但不是我在表中单击的行中的对象(由于在单击列标题时进行排序…我的排序是在IB中设置的,而不是在代码中使用排序描述符) 是否有方法使用tableView.selectedRow作为索引执行以下操作: let

我在IB中对表设置了Double Action,当我在对表排序后双击tableview行时,tableview.selectedRow现在与最初加载它的数组的索引不同

let trade=trades[tableView.selectedRow]
让我查看
trade.tradeNo
和其他模型元素,但不是我在表中单击的行中的对象(由于在单击列标题时进行排序…我的排序是在IB中设置的,而不是在代码中使用排序描述符)

是否有方法使用tableView.selectedRow作为索引执行以下操作:

let trade = arrayController.selectedObjects as! [TradeMode]
但这不起作用。。。。没有tr.tradeNo

在我的一生中,我无法找到如何获取行的数据

我已经迭代了arrayController.arrangedObjects,如下所示

用于置换arrayController.arrangedObjects作为[TradeModel]{
..
我可以看到所有正确的数据。。 例如
trade.tradeNo

但我只想使用一个索引,然后抓取我双击的行

我所做的所有web搜索都不断地提出如何将tableview绑定到array controller……这一切都设置得很好,工作得很好。这是问题的图片……不是下面表格中突出显示的按日期递减排序的行。selectedRow 5不再是详细信息弹出屏幕中显示的数组“交易”中的索引5

[2018-10-06]:我找到了一个可行的解决方案,尽管我不确定它是否是最好的。在双击后,我正在将arrayController.arrangedObjects复制到一个新阵列中

让tr=arrayController.arrangedObjects为![Trade]

这个数组(tr)现在所有的交易都是按排序的。所以当我使用tr[tableView.selectedRow].tradeNo时,我得到了正确的交易

再一次,我不确定我是否为我的应用程序做了最好的事情。我正在尝试使用Swift和KVO以及arrayController来完成所有繁重的工作。因此,我仍然在质疑如何正确地做到这一点


IB中是否有arrayController(如绑定)的设置,用于选择索引和排序描述符等,以保留我的原始阵列(交易)与arrayController中的更改同步?也许我真的不希望发生这种情况。我只是还不知道。

我通过临时创建自定义对象的副本作为NSMutableArray,使用NSArrayController sortDescriptors对其排序,并将原始数组设置为排序后的数组作为自定义对象,找到了此解决方案。当您单击表格标题以便表格行按例如
tradeNo
排序时,sortDescriptor将被发送到NSTableViewDataSource,我们可以在那里使用
SortDescriptorsIDChange
获取它

将表视图的
数据源
绑定到
ViewController
并为其创建扩展。(关于行选择的两行没有直接关系,但您可能想知道在实现解决方案后如何执行。)

虽然这个解决方案有效,但它在绑定到表视图的文本字段(通过试用也直接绑定到数组)方面产生了一些问题为了持续更新。所以我敢于尝试全IB解决方案,并最终找到了解决方案。这种方法需要一些不同的配置,例如,不通过
控制器键|>排列对象
模型键路径|>tradeNo
,将单个列
表格单元格视图
绑定到ArrayController,但de>Table View。这在一开始进行连续更新时效果很好,但是,一旦通过单击正在运行的应用程序中的Table View标题应用了排序描述符,
连续更新值
也会导致意外行为。通过禁用它,该行为与上述解决方案的行为相同

如果有兴趣的话,我可能会在后面添加一个小的演练,但是编程解决方案应该可以工作

另外,仅供参考,我只让它与Swift4一起使用。从4.2开始,我能找到的所有指南中的绑定(IB)方法都被弃用;苹果的文档也一样,没有提及关键的更改

class ViewController: NSViewController {

    @objc dynamic var objects: [Object] = []
    // ...
}


extension ViewController: NSTableViewDataSource {

    func tableView(_ tableView: NSTableView, sortDescriptorsDidChange oldDescriptors: [NSSortDescriptor]) {

        let rowToBeSelected = IndexSet(integer: (tableView.selectedRow))

        guard let sortDescriptor = tableView.sortDescriptors.first else { return }
        let objectsAsArray = NSMutableArray(array: objects)
        objectsAsArray.sort(using: [sortDescriptor]) //: or skip the "guard let" and use "tableView.sortDescriptors".  Perhaps someone has advice on good practice here.
        objects = objectsAsArray as! [Object]

        tableView.reloadData()
        tableView.selectRowIndexes(rowToBeSelected, byExtendingSelection: false)

    }
}