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