简体   繁体   中英

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.

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

我的应用当前显示了它

一个例子必须是

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. The subDirectories property of Directories should be an array of Directories . The directories property of ViewController points to a tree of directories and can be a 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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