Swift 3 - 带有可扩展项的 NSOutlineView
Swift 3 - NSOutlineView with expandable items
我想实现一个 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 属性的字典或自定义 objects 而不是项目字符串。 children 属性 是 child 项的数组。
func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any
return是item
的child人。如果 item
为 "Item 1" 且 index
为 1,则 return 值为 "Sub Item 1.2"。
func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int
returns``的children数。如果 item
为 "Item 1" ,则 return 值为 2.
一个简单的String
数组在这里用处不大,你至少需要一个字典来显示子项。我建议引入一个小辅助模型,我们称之为 Item
。它包含一个名称和一些 children 项,这些将是 sub-items.
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
}
}
在名为 items
的 viewController 上声明一个 属性,并使用 itemsForNumberOf
辅助函数声明 return 一些 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
}
查看 NSOutlineViewDataSource and in specific this API
的文档
func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
if item == nil {
return items[index]
}
if let item = item as? Item, item.childrens.count > index {
return item.childrens[index]
}
return ""
}
Return 根据收到的项目 children 展开 属性。
如果为空,则没有children -> 不可扩展
如果它不为空,则有 children -> expandable
func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
guard let item = item as? Item else {
return false
}
return !item.childrens.isEmpty
}
同样 return 再次使用 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
函数中,您需要确保 return nil
所有内容,而不是 Item
类型的请求视图。
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
}
}
我想实现一个 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 属性的字典或自定义 objects 而不是项目字符串。 children 属性 是 child 项的数组。
func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any
return是item
的child人。如果 item
为 "Item 1" 且 index
为 1,则 return 值为 "Sub Item 1.2"。
func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int
returns``的children数。如果 item
为 "Item 1" ,则 return 值为 2.
一个简单的String
数组在这里用处不大,你至少需要一个字典来显示子项。我建议引入一个小辅助模型,我们称之为 Item
。它包含一个名称和一些 children 项,这些将是 sub-items.
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
}
}
在名为 items
的 viewController 上声明一个 属性,并使用 itemsForNumberOf
辅助函数声明 return 一些 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
}
查看 NSOutlineViewDataSource and in specific this API
的文档func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
if item == nil {
return items[index]
}
if let item = item as? Item, item.childrens.count > index {
return item.childrens[index]
}
return ""
}
Return 根据收到的项目 children 展开 属性。
如果为空,则没有children -> 不可扩展
如果它不为空,则有 children -> expandable
func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
guard let item = item as? Item else {
return false
}
return !item.childrens.isEmpty
}
同样 return 再次使用 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
函数中,您需要确保 return nil
所有内容,而不是 Item
类型的请求视图。
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
}
}