Как расшириться от ребенка до самого первого родителя? - PullRequest
0 голосов
/ 30 мая 2019

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

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

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

Код не готов. Существует много тестирования и отладки.

Я добавил весь соответствующий код к этим вопросам.

Пока что мое приложение читает каталоги, и если в этом каталоге есть какой-либо mp3-файл, он отображается в виде таблицы, но это не часть моего вопроса, а просто фон.

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

@objc func singleClick()
{
    if let item = self.outlineView.item(atRow: self.outlineView.selectedRow)  {
        self.arrMp3File.removeAll()
        do {
            let xx = (item as! DirectoryItem).url
            let b = self.getSubDir(path: xx.path)
            self.saveDefaults(url: xx)
            DispatchQueue.global(qos: .background).async { [weak self] in
                DispatchQueue.main.async {
                    self?.progressIndicator.isHidden = false
                    self?.progressIndicator.startAnimation(self)
                }
                for bb in b {
                    self?.getTagsFromFile(file: xx.path+"/"+bb)
                }
                DispatchQueue.main.async {
                    self?.arrMp3File.sort(by: {
                        $0.file < $1.file
                    })
                    self?.tableView.reloadData()
                    self?.loadTagsFromButton.isEnabled = true
                    self?.progressIndicator.stopAnimation(self)
                    self?.progressIndicator.isHidden = true
                }
            }
        }
    }   

}

override func viewDidLoad() {
    super.viewDidLoad()
     let defaults = UserDefaults.standard

    let lastDirectory = defaults.url(forKey: "LastDirectory")
    print(lastDirectory ?? "")
   // rootItem = DirectoryItem(url: lastDirectory ?? FileManager.default.homeDirectoryForCurrentUser)
   // getDir(path: age)
    outlineView.dataSource = self
    outlineView.delegate = self

    tableView.delegate = self
    tableView.dataSource = self

    tableView.doubleAction = #selector(doubleClickOnResultRow)
  //  outlineView.action = #selector(singleClick)


  self.progressIndicator.isHidden = true
    self.tableView.reloadData()

}

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

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


class DirectoryItem {

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

}

}

What I would like to show

What is shown at the moment

1 Ответ

1 голос
/ 30 мая 2019

Если вы сохранили URL-адрес, который последний раз посещал пользователь, вы можете отобразить и выбрать его в три этапа:

  1. Преобразовать URL-адрес в массив DirectoryItem, представляющийкомпоненты пути URL.

  2. Попросите в режиме структуры развернуть каждый из этих элементов, начиная с элемента, который является прямым потомком корневого узла.

  3. Попросите в режиме структуры выбрать последний элемент.

Непроверенный код:

func reveal(_ url: URL) {
    // Step 1.
    let items = itemHierarchy(for: url)

    // Step 2.
    for item in items {
        outlineView.expandItem(item)
    }

    // Step 3.
    if
        let last = items.last,
        case let row = outlineView.row(forItem: last),
        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
}
...