2017-05-07 107 views
1

我想實現一個outlineView,它將字符串值顯示爲根值。下面的代碼工作對我來說:Swift 3 - 帶可擴展項目的NSOutlineView

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 
    } 

} 

這是結果:

enter image description here

,但我不知道,我怎麼能對第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 

... 

有人可以幫助我嗎?

回答

0

一個簡單的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的屬性,並返回一些Item的使用itemsForNumberOf助手功能。

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文件和具體這個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 "" 
} 

返回expandalbe屬性根據接收到的項目的兒童。
如果是空的,沒有孩子 - >不可擴展
如果它不是空的,有孩子 - >擴張

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

    return !item.childrens.isEmpty 
} 

同爲返回的子項使用兒童財產再次

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返回到所有內容,而不是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 
    } 
} 

你應該有這樣的事情結束了:
enter image description here

0

如果要顯示分層數據,數據不能是簡單的字符串數組。使用字典或具有標題/名稱和子級屬性的自定義對象來代替項目字符串。兒童財產是一系列兒童物品。

func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any返回item的子女。如果item是「項目1」而index是1,則返回值是「子項目1.2」。

func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int返回``的孩子數量。如果item是「Item 1」,則返回值爲2.