Swift3 Swift 3-带可扩展项目的NSOutlineView

Swift3 Swift 3-带可扩展项目的NSOutlineView,swift3,xcode8,nsoutlineview,Swift3,Xcode8,Nsoutlineview,我想实现一个outlineView,它将字符串值显示为根值。以下代码适用于我: import Cocoa class TestController: NSViewController, NSOutlineViewDataSource, NSOutlineViewDelegate { @IBOutlet weak var outlineView: NSOutlineView! var items: [String] = ["Item 1", "Item 2", "Item 3",

我想实现一个outlineView,它将字符串值显示为根值。以下代码适用于我:

import Cocoa


class TestController: NSViewController, NSOutlineViewDataSource, NSOutlineViewDelegate {


    @IBOutlet weak var outlineView: NSOutlineView!

var items: [String] = ["Item 1", "Item 2", "Item 3", "Item 4","Item 5"]

func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
        return items[index]
    }


    func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
        return true
    }


    func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
        if item == nil {
         return items.count
        }
        return 0
    }


    func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {

        let v = outlineView.make(withIdentifier: "HeaderCell", owner: self) as! NSTableCellView
        if let tf = v.textField {
            tf.stringValue = item as! String
        }
        return v
    }

}
结果是:

但我不知道如何为项目1分配不同的字符串值(例如)。我希望实现这样的目标:

+Item 1
++Sub Item 1.1
++Sub Item 1.2

+Item 2
++Sub Item 2.1

+Item 3
++Sub Item 3.1
++Sub Item 3.2
++Sub Item 3.3

...

有人能帮我吗?

如果要显示分层数据,数据不能是简单的字符串数组。使用具有title/name和children属性的字典或自定义对象,而不是项字符串。children属性是子项的数组

func-outlineView(\outlineView:NSOutlineView,子索引:Int,of item item:Any?->Any
返回
项的子项。如果
项目
为“项目1”且
索引
为1,则返回值为“子项目1.2”


func-outlineView(\outlineView:NSOutlineView,numberOfChildrenOfItem-item:Any?)->Int
返回``的子级数。如果
item
为“item 1”,则返回值为2。

一个简单的
String
数组在这里不会太有用,您至少需要一个字典来显示子项。我建议引入一个小助手模型,我们称之为
Item
。它包含一个名称和一些子项,这些子项将是子项

struct Item {
    let name: String
    var childrens: [Item] = []

/// Create a helper function to recursivly create items
///
/// - Parameters:
///   - parents: number of parent items 
///   - childrens: number of children for each parent item
/// - Returns: array of Item
static func itemsForNumberOf(parents: Int, childrens: Int) -> [Item] {
    var items: [Item] = []
    for parentID in 1...parents {
        var parent = Item(name: "Index \(parentID)",childrens: [])
        for childrenID in 1...childrens {
            let children = Item(name: "Index \(parentID).\(childrenID)",childrens: [])
            parent.childrens.append(children)
        }
        items.append(parent)
    }
    return items
}
}

在viewController上声明名为
items
的属性,并使用
itemsForNumberOf
帮助函数返回一些
Item

class TestController: NSViewController, NSOutlineViewDataSource, NSOutlineViewDelegate {

    let items: [Item] = {
        return Item.itemsForNumberOf(parents: 5, childrens: 3)
    }()

    @IBOutlet weak var outlineView: NSOutlineView!
}
TestController
中,覆盖
viewDidLoad()
函数,并将委托和数据源分配给您的viewController

override func viewDidLoad() {
    super.viewDidLoad()
    self.outlineView.delegate = self
    self.outlineView.dataSource = self
}
检查本文件的文档,并具体检查

基于所接收项目的子项返回expandalbe属性。
如果为空,则无子项->不可展开
如果不为空,则具有子项->可展开

func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
    guard let item = item as? Item else {
        return false
    }

    return !item.childrens.isEmpty
}
再次使用childrens属性返回子项计数的方法相同

func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
    if item == nil {
        return items.count
    }

    if let item = item as? Item {
        return item.childrens.count
    }

    return 0
}
viewFor
函数中,您需要确保将
nil
返回给所有内容,而不是请求查看的
项目

    func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {

        guard let item = item as? Item else {
            return nil
        }

        let v = outlineView.make(withIdentifier: "HeaderCell", owner: self) as! NSTableCellView
        if let tf = v.textField {
            tf.stringValue = item.name
        }
        return v
    }
}
你应该以这样的方式结束:

    func outlineView(_ outlineView: NSOutlineView, viewFor tableColumn: NSTableColumn?, item: Any) -> NSView? {

        guard let item = item as? Item else {
            return nil
        }

        let v = outlineView.make(withIdentifier: "HeaderCell", owner: self) as! NSTableCellView
        if let tf = v.textField {
            tf.stringValue = item.name
        }
        return v
    }
}