Xcode9 Swift4.2 NSOutlineView NSTreeController данные - PullRequest
0 голосов
/ 17 ноября 2018

Я пытаюсь создать контурное представление в приложении MacOS, которое имеет уровни множественности, которые являются сводными данными для набора данных, хранящихся в SQLite3.У меня есть наброски, работающие с древовидным контроллером с очень простым NSMutuableDictionary на основе класса модели.

import Cocoa
class Summary: NSObject {
    @objc dynamic var name: String
    @objc dynamic var trades: Int
    @objc dynamic var avgPL: Double
    @objc dynamic var pandl: Double
    @objc dynamic var parent: String
    @objc dynamic var isLeaf: Bool
    @objc dynamic var childCount: Int
    @objc dynamic var children: [Summary] = []
    init(name: String, trades: Int, avgPL: Double, pandl: Double, parent: String, isLeaf: Bool,childCount: Int) {
        self.name = name
        self.trades = trades
        self.avgPL = avgPL
        self.pandl = pandl
        self.parent = parent
        self.isLeaf = isLeaf
        self.childCount = childCount
    }
    @objc func add(child: Summary) {
        children.append(child)
    }
}

Мой простой пример данных:

    let root: [String : Any] = ["name": "Overall","trades":5,"avgPL":200,"pandl":500,"parent":"","isLeaf": false,"childCount": 2 ]
    let dict: NSMutableDictionary = NSMutableDictionary(dictionary: root)
    let l2a = Summary(name: "L2a", trades: 3, avgPL: 100, pandl: 300, parent: "L1",isLeaf: true,childCount: 0)
    let l2b = Summary(name: "L2b", trades: 2, avgPL: 100, pandl: 200, parent: "L1",isLeaf: true,childCount: 0)
    dict.setObject([l2a,l2b], forKey: "children" as NSCopying)

Я передаю словарь в TreeController:

treeController.addObject(dict)

И это прекрасно работает, давая мне складной контур:

enter image description here

Но я понятия не имею, как добавить ещеуровни или дети для детей.Я хочу иметь до четырех уровней в общих чертах.У меня работают все сводки SQL, и я пробовал так много вариантов заполнения массивов и пытался создать словарь с данными безрезультатно.У меня есть children, childCount и isLeaf, установленные на все, но treecontroller не нравится массив, жалующийся на то, что isLeaf не совместим с KVO.Мои данные в массиве выглядят так (не все данные, но достаточно, чтобы увидеть, что я делаю). Основной уровень и все последующие дочерние элементы основаны на классе модели Summary выше.Могу ли я просто преобразовать этот массив в словарь?Или я могу сделать его совместимым с KVO, добавив ключи к классу модели или что-то еще?У меня есть все 4 уровня в отдельных массивах, которые я использую для построения результирующего массива, если это полезно:

enter image description here

Я должен добавить, что у меня естьNSObject определен как NSMutableArray, а его содержимое связано с treeController.Мой treeController привязан к каждой переменной в классе модели и на верхнем уровне имеет:

enter image description here

Если я передам массив, который я построил, в treeControllerЯ получаю следующую ошибку:

Failed to set (contentViewController) user defined inspected property on (NSWindow): [<_TtGCs23_ContiguousArrayStorageC11outlinetest7Summary_ 0x604000445160> addObserver:forKeyPath:options:context:] is not supported. Key path: isLeaf

1 Ответ

0 голосов
/ 25 ноября 2018

После создания моего NSOutlineView без NSTreeController и получения всего работающего, я все еще хотел вернуться к этому и реализовать treeController, чтобы воспользоваться преимуществами механизма сортировки, который он предоставляет.И я обнаружил согласно моему последнему комментарию, что у меня что-то не так в InterfaceBuilder, из-за чего он жаловался на соответствие KVO.У меня все было правильно подключено, за исключением привязки Content Array на treeController.Здесь я привязал его к своему ViewController и добавил свой массив данных reportSummary в путь ключа модели.

enter image description here

Мне также больше не нужно добавлять вручнуюмой массив данных в treeController, используя treeController.addObject(reportSummary).Когда это сработало, я смог выполнить сортировку, и все работает хорошо.Следует отметить две вещи:

  1. Настройка сортировки в TreeController немного отличается от настройки ArrayController, привязанного к TableView.При просмотре таблицы было достаточно указать, какие столбцы можно сортировать в инспекторе удостоверений в IB.Но в сценарии outlineView мне также нужно было настроить привязки в IB к treeController и изменить ключ контроллера с arrangedObjects на sortDescriptors.

  2. При тестировании моего схематичного вида с контуром дерева я столкнулся с проблемой, когда дважды щелкнул по итоговой строке.Я реализовал Double Action в outlineView в IB, чтобы контролировать расширение и свертывание сводных разделов.Обратите внимание, что я читал об этом в потоке здесь, и кто-то упомянул, что вам нужно будет поддерживать несколько массивов и отслеживать индексы, потому что после свертывания или развертывания строки изменяется номер строки всех последующих строк.Но я понял, что решение состоит в том, чтобы просто перебирать строки в обратном порядке и расширять или сворачивать их, возвращаясь к дереву, начиная с outlineView.numberOfRows-1.Это работает хорошо, и наряду с двойным действием (щелчком), чтобы развернуть и свернуть, я также добавил NSSlider, который отслеживает уровень расширения и позволяет мне свернуть все самые низкие уровни, перемещаясь назад вверх по дереву, вместо того, чтобы щелкать все маленькие стрелки в каждой строке.,Это сломалось, когда я реализовал treeController.Я получил ошибку

Не удалось привести значение типа 'NSKVONotifying_NSTreeControllerTreeNode'

Эта строка кода была проблемой

let summary = reportOutline.item(atRow: x) as! Summary

Мне пришлось изменить это на

let node = reportOutline.item(atRow: x) as! NSTreeNode
let summary = node.representedObject as! Summary

И это все.Работаем прекрасно сейчас.

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