如何从一个孩子扩展到其第一个父母? [英] How to expand from a child to its very first parent?

查看:44
本文介绍了如何从一个孩子扩展到其第一个父母?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从根(父级的父级....)开始扩展所有子级,直到真正的节点为止.如何在不单击每个节点的情况下做到这一点?

I'm trying to expand all children starting on root(parent of a parent....) until the actual node. How can I do it without clicking on every node?

我正在使用它来显示目录内容,并且我想显示用户在关闭/打开应用程序之前的最后路径.

I'm using it to show directories content and I would like to show the last path the user was before closing/opening the app.

第一张图片显示了我想要的样子,第二张图片显示了当前显示的内容.

The first picture shows how I would like it to be and the second picture shows what is shown at the moment.

代码未完成.有很多测试和调试.

The code is not done. There is a lot of testing and debugging.

我在此问题中添加了所有相关代码.

I added all relevant code to this questions.

到目前为止,我的应用程序读取目录,并且如果此目录上有任何mp3文件,它将显示在表格视图中,但这不是我的问题的一部分,而只是背景.

So far my app reads directories and if there is any mp3 file on this directory it is shown on a table view, but it is not part of my question, just a background.

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

}

}

推荐答案

如果您保存了用户上次访问的URL,则可以通过三个步骤显示并选择它:

If you have saved the URL that the user was last visiting, then you can show and select it in three steps:

  1. 将URL转换为表示URL路径组成部分的 DirectoryItem 数组.

询问大纲视图以展开每个项目,从作为根节点直接子项的项目开始.

Ask the outline view to expand each of those items, starting with the item that is a direct child of the root node.

询问大纲视图以选择最后一项.

Ask the outline view to select the last item.

未经测试的代码:

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
}

这篇关于如何从一个孩子扩展到其第一个父母?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆