После сортировки таблицы NSTableview, связанной с NSArrayController, выбранная строка больше не соответствует элементу массива - PullRequest
0 голосов
/ 04 октября 2018

У меня настроено Double Action в IB на таблице, и когда я дважды щелкаю строку таблицы после сортировки таблицы, tableview.selectedRow теперь отличается от индекса массива, из которого он был изначально загружен.

let trade = trades[tableView.selectedRow] позволяет мне видеть trade.tradeNo и другие элементы модели, но это не объект из строки, по которой я щелкнул в таблице (из-за сортировки, если я щелкнул заголовок столбца ...моя сортировка настроена в IB, а не в коде, использующем sortDescriptors).

Есть ли способ использовать tableView.selectedRow в качестве индекса, чтобы сделать что-то вроде:

let trade = arrayController.selectedObjects as! [TradeMode]

Но это не работает.... нет tr.tradeNo

За свою жизнь я не могу узнать, как получить данные строки.

Я перебрал массив arrayController.arrangedObjects, подобный этому

for trade in arrayController.arrangedObjects as [TradeModel]{ .... и я могу видеть все правильные данные .. например, trade.tradeNo и т. Д.

Но я просто хочу использовать индекс и перейти к строке, по которой я дважды щелкнул.

Весь веб-поиск, который я делал, продолжает придумывать, как сделать привязки tableview к контроллеру массива ... это все настроено и работает хорошо.Вот фотография проблемы .... не выделенная строка в таблице ниже, отсортированная по убыванию даты.selectedRow 5 больше не является индексом 5 в массиве 'trades', отображаемом на всплывающем экране сведений

TableView с всплывающим экраном сведений

[2018-10-06]Я нашел работоспособное решение, хотя я не уверен, что оно лучшее.После того, как двойное действие (двойной щелчок) выполнено, я делаю копию arrayController.arrangedObjects в новый массив

let tr = arrayController.arrangedObjects as![Trade]

В этом массиве (tr) все сделки теперь находятся в отсортированном порядке.Поэтому, когда я использую tr [tableView.selectedRow] .tradeNo, я получаю правильную сделку.

Опять же, я не уверен, что делаю лучшее для своего приложения.Я пытаюсь использовать Swift и KVO и arrayController, чтобы сделать всю тяжелую работу.Итак, я все еще задаюсь вопросом, как сделать это правильно.

Есть ли в IB настройки для arrayController (например, в Bindings) для selectionIndexes и sortDescriptors и т. Д., Которые будут поддерживать мой исходный массив (сделки) в синхронизациис изменениями в массиве Controller?Возможно, я действительно не хочу, чтобы это произошло.Я просто еще не знаю.

1 Ответ

0 голосов
/ 16 мая 2019

Я нашел это решение, временно создав копию пользовательского объекта как NSMutableArray, отсортировав его с помощью sortDescriptors NSArrayControllers и установив исходный массив в отсортированный массив в качестве пользовательского объекта.Когда вы щелкаете заголовок таблицы, чтобы строки таблицы сортировались, например, по tradeNo, sortDescriptor отправляется в NSTableViewDataSource, где мы можем извлечь его, используя sortDescriptorsDidChange.

Привязать * 1005 представления вашей таблицы* до 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 и в конце концов понял это.Этот подход требует некоторых других конфигураций, например, не привязывать отдельные столбцы Table Cell View к ArrayController через Controller Key |> arrangedObjects, Model Key Path |> tradeNo, но Table View.Вначале это работало нормально при постоянном обновлении, однако, после того, как sortDescriptors был применен посредством щелчка по заголовку табличного представления в запущенном приложении, Continuously Updates Value также вызвало непредвиденное поведение.И, деактивировав его, поведение будет таким же, как и в приведенном выше решении.

Возможно, позже я добавлю небольшой обзор, если есть интерес, но программное решение должно работать.

Кроме того, к вашему сведению, я получил его только для работы со Swift4.Начиная с 4.2, методы привязки (IB) из всех руководств, которые я смог найти, устарели;Как и в документации Apple, без ссылки на важные изменения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...