Как расширить дочерний элемент NSOutlineView?

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

Я заполняю схему просмотра каталогами. Каждый раз, когда элемент расширяется, загружаются его подкаталоги.

У меня была некоторая помощь (Как расширяться от дочернего элемента к его самому первому родителю?), что делает корень выбранным и развернутым.

При расширении элемента я сохраняю местоположение. Таким образом, в следующий раз, когда приложение откроется, оно покажет все элементы, развернутые от корня до сохраненного пути.

Например, когда я выбираю «Рабочий стол», закрываю и открываю приложение, оно показывает, что «Рабочий стол» выбран и развернут.

Если я выберу dial или mp на рабочем столе, я смогу сохранить путь, но при открытии он вернется к корню, и ничего не будет выбрано или расширено.

Конечный результат будет с выбранным и расширенным циферблатом или mp.

у функции expandItem есть параметр expandChild, но он расширяет все. Я хочу расширяться только до сохраненного пути.

введите здесь описание изображения

var rootItem = DirectoryItem(url: FileManager.default.homeDirectoryForCurrentUser)

override func viewDidLoad() {
    super.viewDidLoad()
    let defaults = UserDefaults.standard
    let lastDirectory = defaults.url(forKey: "LastDirectory")
    outlineView.dataSource = self
    outlineView.delegate = self
    tableView.delegate = self
    tableView.dataSource = self
    tableView.doubleAction = #selector(doubleClickOnResultRow)
    self.progressIndicator.isHidden = true
    self.tableView.reloadData()
    self.outlineView.reloadData()
    reveal(URL(string: lastDirectory!.lastPathComponent) ?? FileManager.default.homeDirectoryForCurrentUser)       
}


func reveal(_ url: URL) {
    let items = itemHierarchy(for: url)
    for item in items {
        outlineView.expandItem(item, expandChildren: false)
        let row = outlineView.row(forItem: item)
        if(row != -1) {
            let set = IndexSet(integer: row)
            outlineView.selectRowIndexes(set, byExtendingSelection: false)
        }
    }
}

private func itemHierarchy(for url: URL) -> [DirectoryItem] {
    var items: [DirectoryItem] = []
    var current: DirectoryItem = rootItem

    for component in url.pathComponents {
        guard let child = current.childItems.first(where: { $0.name == component }) else {
            return items
        }
        items.append(child)
        current = child
    }

    return items
}


extension ViewController: NSOutlineViewDataSource {
    func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
        let directoryItem = item as? DirectoryItem ?? rootItem

        return directoryItem.childItems.count
    }

    func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
        let directoryItem = item as? DirectoryItem ?? rootItem
        return directoryItem.childItems[index]
    }

    func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
        let directoryItem = item as? DirectoryItem ?? rootItem
        return directoryItem.isExpandable
    }
}

extension ViewController: NSOutlineViewDelegate {
    func outlineViewSelectionDidChange(_ notification: Notification) {
        singleClick()       
    }

    func outlineView(_ outlineView: NSOutlineView, shouldExpandItem item: Any) -> Bool {
        let directoryItem = item as? DirectoryItem ?? rootItem
        return (directoryItem.childItems.count != 0)
    }

    func outlineView(_ outlineView: NSOutlineView, shouldShowOutlineCellForItem item: Any) -> Bool {
        let directoryItem = item as? DirectoryItem ?? rootItem
        return (directoryItem.childItems.count != 0)
    }

    func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
        var text = ""
        if let directories = item as? DirectoryItem {

            if(directories.isdir) {
                text = directories.name
                let tableCell = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "cell"), owner: self) as! NSTableCellView
                tableCell.textField!.stringValue = text
                return tableCell
            }
        }
            return nil
    }
}







class Directories {
    var name: String
    var subDirectories: [String]

    init(name: String, subDirectories: [String]) {
        self.name = name
        self.subDirectories = subDirectories
    }
}


class DirectoryItem: CustomDebugStringConvertible {

    var name: String
    var url: URL
    var isdir: Bool
    var prev: URL

    lazy var isExpandable: Bool = {
        do {
            return try url.resourceValues(forKeys: [.isDirectoryKey]).isDirectory ?? false
        } catch let error as NSError {
            return false
        }
    }()

    lazy var childItems: [DirectoryItem] = {
        do {
            let urls = try FileManager.default.contentsOfDirectory(at: url,
                                                                   includingPropertiesForKeys: [.isDirectoryKey],
                                                                   options: [.skipsHiddenFiles])

            var aa: [DirectoryItem]
            var bb: [DirectoryItem]
            bb = []
            aa = urls.map { DirectoryItem(url: $0) }
            for a in aa {
                if(a.isdir) {
                    bb.append(a)
                    // print(a)
                }

            }
            return bb
            //return urls.map { DirectoryItem(url: $0) }
        } catch let error as NSError {
            return []
        }
    }()

    init(url: URL) {
        self.url = url
        self.name = url.lastPathComponent
        self.isdir = url.hasDirectoryPath
        self.prev = url.deletingLastPathComponent()

    }

    public var debugDescription: String {
    return """

    - url: \(self.url)
    - name: \(self.name)
    - isdir: \(self.isdir)
    - prev: \(self.prev)

    """
    }

}

person Renan Aguiar    schedule 07.06.2019    source источник
comment
Каковы значения url и items в reveal?   -  person Willeke    schedule 07.06.2019
comment
на viewDidLoad я вызываю раскрыть (URL (строка: lastDirectory!.lastPathComponent) ?? FileManager.default.homeDirectoryForCurrentUser)   -  person Renan Aguiar    schedule 07.06.2019
comment
Почему вы делаете URL(string: lastDirectory!.lastPathComponent)?   -  person Willeke    schedule 08.06.2019
comment
Если я использую только lastDirectory, он даже не показывает раскрытый и выбранный первый уровень   -  person Renan Aguiar    schedule 08.06.2019
comment
Вы проверили значения url и items?   -  person Willeke    schedule 08.06.2019
comment
да вроде правильно. значения показывают мне имена каждого компонента пути... но он не проходит охрану.   -  person Renan Aguiar    schedule 09.06.2019
comment
Значит items не правильно? Является ли первый компонент дочерним элементом root?   -  person Willeke    schedule 09.06.2019
comment
когда я использую: раскрыть (lastDirectory!), items = [] где lastDirectory/url = file:///Users/rca/Desktop/mp/   -  person Renan Aguiar    schedule 09.06.2019
comment
Каков первый компонент lastDirectory? Это ребенок root?   -  person Willeke    schedule 09.06.2019
comment
print(url.pathComponents) показывает: [/, Users, rca, Desktop, mp]   -  person Renan Aguiar    schedule 09.06.2019