Finderのカラム表示を実現するやつだ。

こんなのを作ってみる。

001

データのクラスを用意する。

class Node {
    // 表示名
    var name:String
    // 子要素
    var children:[Node]
    
    init(name:String) {
        self.name = name
        self.children = [Node]()
    }
}

ViewControllerクラスにNSBrowserDelegateプロトコルを実装する。"class ViewController: NSViewController"の後に", NSBrowserDelegate"を追加する。必要なメソッドや表示するデータをクラスに追加する。

表示するデータのメンバ変数を追加。

    var rootNode = Node(name: "ROOTNODE")

viewDidLoad()でデータの初期化する。

        // データを用意(↓このようなデータ)
        // item0
        // item1 -+- item1-0
        //        +- item1-1 -+- item1-1-0
        //        |           +- item1-1-1
        //        +- item1-2
        // item2
        // item3
        for i in 0..<4 {
            rootNode.children.append(Node(name: "item\(i)"))
        }
        for i in 0..<3 {
            rootNode.children[1].children.append(Node(name: "item1-\(i)"))
        }
        for i in 0..<2 {
            rootNode.children[1].children[1].children.append(Node(name: "item1-1-\(i)"))
        }

必要なメソッドを追加する。

    // ルートアイテムを返す
    func rootItem(for browser: NSBrowser) -> Any? {
        return rootNode
    }

    // 子要素のアイテムの数を返す
    func browser(_ browser: NSBrowser,
                 numberOfChildrenOfItem item: Any?) -> Int {
        let node = item as! Node
        return node.children.count;
    }

    // index番のアイテムを返す
    func browser(_ browser: NSBrowser,
                 child index: Int,
                 ofItem item: Any?) -> Any {
        let node = item as! Node
        return node.children[index]
    }
    
    // リーフかどうかを返す
    //   子要素がない場合はtrue(リーフアイテムだよって意味)を返す
    func browser(_ browser: NSBrowser,
                 isLeafItem item: Any?) -> Bool {
        let node = item as! Node
        return node.children.count == 0 ? true:false
    }

    // アイテムの表示文字列を返す
    func browser(_ browser: NSBrowser,
                 objectValueForItem item: Any?) -> Any? {
        let node = item as! Node
        return node.name
    }

ストーリーボードを開いてNSBrowserを貼り付けてdelegateとView Controllerを接続する。

これで完成!w