简体   繁体   English

如何向目录树之类的NSOutlineView上的节点添加更多节点?

[英]How to add more nodes to nodes on a NSOutlineView like a directory tree?

I would like to get and show the user home directory on a NSOutlineView going deep every time the node is expandable. 我想在每次节点可扩展时在NSOutlineView上显示用户主目录的深度。

So far I can get only the first level and expand it to a second level. 到目前为止,我只能获得第一级并将其扩展到第二级。

I imagine that it has to be appended to an index or something like that. 我想它必须附加到索引或类似的东西上。

I can get level 1 and 2. When i click on the level 2, for example Documents, there is a directory, yourDirectoryName, that has more directories in it. 我可以得到1级和2级。当我单击2级时,例如Documents,有一个目录yourDirectoryName,其中包含更多目录。 I would like to show the arrow and be able to keep going further on the tree 我想显示箭头,并能够在树上继续前进

First pic is my app. 第一张照片是我的应用程序。 Second pic is an example from filezilla 第二张图片是filezilla的示例

我的应用当前显示了它

一个例子必须是

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

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

class ViewController: NSViewController {
var directories = [Directories]()
@IBOutlet weak var outlineView: NSOutlineView!

override func viewDidLoad() {
    super.viewDidLoad()
    getDir(path: "")
    outlineView.dataSource = self
    outlineView.delegate = self
}



func getDir(path: String) {
     let fm = FileManager.default.homeDirectoryForCurrentUser

    do {
        let items = contentsOf(folder: fm)
        for item in items {
            let sub = getSubDir(path: item.lastPathComponent)
            let re = Directories(name: item.lastPathComponent, subDirectories: sub)
            directories.append(re)
        }
    }
}

func contentsOf(folder: URL) -> [URL] {
    let fileManager = FileManager.default
    do {
        let contents = try fileManager.contentsOfDirectory(atPath: folder.path)

        let urls = contents.map { return folder.appendingPathComponent($0) }
        return urls
    } catch {
        return []
    }
}

func getSubDir(path: String) -> [String]{
    var sub = [String]()
    let fm = FileManager.default
    let filePath = NSString(string: path).expandingTildeInPath
    do {
        let items = try fm.contentsOfDirectory(atPath: filePath)
        for item in items {
            sub.append(item)
        }
    } catch {
        // failed to read directory
    }
    return sub
}

override var representedObject: Any? {
    didSet {
        // Update the view, if already loaded.
    }
}
}



extension ViewController: NSOutlineViewDataSource {
func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
    if let directories = item as? Directories {
        return directories.subDirectories[index]
    }
    return directories[index]
}

func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
    if let directories = item as? Directories {
        return directories.subDirectories.count > 0
    }
    return false
}

func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
    if let directories = item as? Directories {
        return directories.subDirectories.count
    }
    return directories.count
}
}

extension ViewController: NSOutlineViewDelegate {
func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
    var text = ""
    if let directories = item as? Directories {
        text = directories.name
    }
    else {
        text = item as! String
    }

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

Expanding level 2 to 3 is the same as expanding level 1 to 2. A subdirectory is a directory and has its own subdirectories. 将级别2扩展到3与将级别1扩展到2相同。子目录是一个目录,并且具有自己的子目录。 The subDirectories property of Directories should be an array of Directories . subDirectories的属性Directories应的阵列Directories The directories property of ViewController points to a tree of directories and can be a Directories . ViewControllerdirectories属性指向目录树,并且可以是Directories

Example: 例:

class ViewController: NSViewController {

    // the rootItem is invisible
    var rootItem = DirectoryItem(url: FileManager.default.homeDirectoryForCurrentUser)

}


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 outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {
        let directoryItem = item as? DirectoryItem ?? rootItem
        let tableCell = outlineView.makeView(withIdentifier: (tableColumn?.identifier)!, owner: self) as! NSTableCellView
        tableCell.textField!.stringValue = directoryItem.name
        return tableCell
    }

}


class DirectoryItem {

    var name: String
    var url: 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])
            return urls.map { DirectoryItem(url: $0) }
        } catch let error as NSError {
            return []
        }
    }()

    init(url: URL) {
        self.url = url
        self.name = url.lastPathComponent
    }

}

Disclaimer: I'm used to Objective-C and I'm struggling with Swift. 免责声明:我已经习惯了Objective-C,并且在Swift中挣扎。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM