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



我已经在表的 IB 中设置了双重操作,当我在表排序后双击表视图行时,tableview.selectedRow 现在与最初加载它的数组的索引不同。

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

有没有办法使用 tableView.selectedRow 作为索引来做这样的事情:

let trade = arrayController.selectedObjects as! [TradeMode]

但这行不通。没有交易没有

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

我已经迭代了arrayController.arrangedObjects,就像这样

for trade in arrayController.arrangedObjects as [TradeModel]{ ....和我可以看到所有正确的数据。 例如trade.tradeNo等。

但我只想使用索引并抓取我双击的行。

我所做的所有网络搜索都在不断提出如何将表视图绑定到数组控制器......这就是所有设置和工作正常。 这是问题的图片。不是下表中按日期降序排序的突出显示的行。 selected第 5 行不再是详细信息弹出屏幕中显示的"交易"数组中的索引 5

带弹出详细信息屏幕的表格视图

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

let tr = arrayController.arrangedObjects as![贸易]

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

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

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

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

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

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)
}
}

虽然此解决方案有效,但它在我绑定到表视图(并通过试验也直接绑定到数组(以进行连续更新的文本字段方面产生了一些问题。所以我敢于尝试一个全IB的解决方案,并最终想通了。这种方法需要一些不同的配置,例如,不是通过Controller Key |> arrangedObjectsModel Key Path |> tradeNo将单个列Table Cell View绑定到ArrayController,而是Table View。这在一开始的持续更新中工作得很好,但是,一旦通过单击正在运行的应用程序中的表视图标题应用 sortDescriptor,Continuously Updates Value也会导致意外行为。通过停用它,该行为与上述解决方案的行为相同。

如果有兴趣,也许我稍后会添加一些演练,但编程解决方案应该有效。

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

最新更新