將 CheckBox 嵌入 TableView 中使用

在看此篇之前,一些基本的重點要先參考「Mac Cocoa NSTableView 程式與綁定
 
這一段是記錄把 CheckBox 放在 TableView 中使用所遇到的一些狀況。

這是一個標準的 Column 設計。

image

首先把紅色的部份移除,換成 CheckBox,如下圖。

image

註:其實還有一種方法,就是不移除 Table Cell View,只移除 Table View Cell,然後用 CheckBox 取代 Table View Cell。底下程式也會需要修改。

然後設定 CheckBox 的 Identifier,本例為 tableCheck。

image

底下是程式呈現的片段。

// 資料來源

var data1: [String] = ["abc","123","xyz"]

 

@IBOutlet weak var table: NSTableView!

 

override func viewDidLoad() {

    super.viewDidLoad()

    table.dataSource = self

    table.delegate = self

}

 

...略...

    

// 傳回有多少資料

func numberOfRows(in tableView: NSTableView) -> Int {

   return data1.count

}

   

// 傳回資料

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {

 

   let view = table.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "tableCheck") , owner: self) as! NSButton

    view.title = data1[row]

    return view

}

 

註:如果沒有移除 Table Cell View,而 CheckBox 是在它的下層,則上面的程式變成如下,也就是利用 subviews[0] 找到下層的 CheckBox。最底下程式也是類似處理,就不一一說明了。

// 傳回資料

func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {

 

    let view = table.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: "tableCheck") , owner: self) as! NSTableCellView

    let checkbox = view.subviews[0] as! NSButton

    checkbox.title = data1[row]

    return view

}

 

這是呈現畫面。

image

此時有一個問題,若點選 CheckBox,CheckBox 會有作用,但不會有選擇到 TableView 該列的事件發生。同樣的,若點選 CheckBox 文字後面的空間,雖然會發生 TableView 該列被選取,但 CheckBox 不會有點選的反應。

如果要解決這二件事,就要分別處理 TableView Click 和 CheckBox Click。

這一段是處理 TableView Click,先找到點選該行的 CheckBox,然後更改 CheckBox 的狀態。

 

@IBAction func tableClick(_ sender: Any) {

    let i = table.selectedRow

    if i == -1 { return }

    let checkBox = table.view(atColumn: 0, row: i, makeIfNecessary: false) as! NSButton

    if checkBox.state == .on {

        checkBox.state = .off

    } else {

        checkBox.state = .on

    }

}

 

這一段是處理 CheckBox 的 Click,點選之後會先找到所在的列數,再轉換成 index,再將此 index 所在列設定為選取狀態。

 

@IBAction func checkBoxClick(_ sender: Any) {

    let row = table.row(for: sender as! NSView)

    let index = NSIndexSet(index: row)

    table.selectRowIndexes(index as IndexSet, byExtendingSelection: false)

}

 

最後,若只想操作 CheckBox,不想看選取列有突顯的顏色,將 TableView 的 Highlight 選擇 None 即可。如此一來,也不用處理上面提到 CheckBox Click 之後選取列的設定了。

image

 
還有一種方法,就是在 Table Column 裡面改成放置 Check Box Cell,此時 TableView 會自動切換成 Cell Based,這時就要用 NSCell 的方式處理,但傳回的資料並不是 CheckBox 的 Title,而是其內容,好像是大於 0 的數字就表示選取 CheckBox,在使用上比較不彈性。
 
似乎是 XXX Cell 的元件都可以如此處理。

 

 
 
 
重要度:
文章分類:

發表新回應

借我放一下廣告