0

Environment: View-based NSTableView WITHOUT Bindings.
Problem: Mapping column's checkbox action to its datasource
(i.e., how do I know which row the checkbox event has occurred, in real time?).

Without using IB bindings, how do I associate any particular NSButton/Checkbox action within its respective NSTableView row to its data source?

enter image description here

I want to be able to update the checkbox's respective data array with its UI state (check in box -> 1 in data source).

That is, mapping an array of structs or closures with their 1:1 table entries. Hence, clicking on a 'select'/row updates its respective boolean flag with the data source array.

The following code snippet shows how I populate the UI:

typealias GeoTuple = (geoDesc:String,geoSelected:Int)
var geoList = [GeoTuple]()


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

    var cellView:NSTableCellView?
    let cellID = tableColumn?.identifier

    guard nil != cellID else {
        cellView = NSTableCellView()
        return cellView
    }

    cellView = (tableView.makeViewWithIdentifier(cellID!, owner: self) as? NSTableCellView)

    guard nil != cellView else {
        print("{ODYInitializePricingProductViewController} *** NO CELL VIEW GENERATED *** \n Check cell identifiers.")
        return nil
    }

    let currentTableColumn = ODYInitPricingTableColumnIdentifier(rawValue:cellView!.identifier!)

    switch currentTableColumn! {
...
   case .geoSelectFlag:
        if row < geoList.count  {
            if let selectButton = cellView?.viewWithTag(1) as? NSButton {
                selectButton.integerValue = geoList[row].geoSelected
            }
        }
  ...
  return cellView
}

Question: How do I trap for a specific NSButton-Check toggle event, and associate/map this event to its respective data source: geoList?

Frederick C. Lee
  • 9,019
  • 17
  • 64
  • 105

2 Answers2

1

Connect the checkbox button's target to your table view delegate and set its action to the selector of some action method.

It's probably easiest to set the target and action programmatically in tableView(_:viewForTableColumn:row:). Because the cell view hierarchies within table columns are actually in sub-nibs, connecting them to the objects in your NIB or storyboard scenes can be problematic.

In the action method, you can look up the row by calling rowForView() on the table, passing the sender which the action method receives as a parameter. You can also check the sender's state to determine whether the new value for your data model should be on or off.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • I did about 80% what you suggest. Revision: a) I've used selectButton.action = "checkBoxAction:" - but needed the additional selectButton.target = self. b) (lldb) po self.geoTableView.rowForView(sender) 3 ... It works! Thanks. – Frederick C. Lee Jan 07 '16 at 21:55
0
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView? { ...
...
case .geoSelectFlag:
    if row < geoList.count  {
        if let selectButton = cellView?.viewWithTag(1) as? NSButton {
            selectButton.integerValue = geoList[row].geoSelected
            selectButton.target = self
            selectButton.action = "checkBoxAction:"
        }
    }
...
}

func checkBoxAction(sender:NSButton) {

}

(lldb) po self.geoTableView.rowForView(sender) 3

Frederick C. Lee
  • 9,019
  • 17
  • 64
  • 105