Search code examples
swiftcocoarownstableview

Can't add rows from array of dictionaries to a NSTable programmatically


I would like to be able to programmatically add rows to my Table. It was easy enough to add column headers from an array. I have an array of dictionaries containing the row data I'm able import the csv data into this array.

var rowData = [[String:String]]()

I want to dump this into my table's rows. What am I missing?

I've tried... func numberOfRows() and func tableView() but they have no effect like they do when I create a table with IB

import Foundation
import Cocoa

class TableView:NSObject{

    var tableContainer = NSScrollView.init(frame: NSRect(x:0, y: 0, width: 800, height: 200))
    var tableView:NSTableView = NSTableView(frame: NSRect(x:0, y: 0, width: 800, height: 200))

    func populateHeaders(){
        for x in 0..<headers.count {
            let column = NSTableColumn.init(identifier:NSUserInterfaceItemIdentifier(rawValue: headers[x]))
            tableView.addTableColumn(column)
            column.headerCell = NSTableHeaderCell(textCell: headers[x])
            }
        }





    override init (){
        super.init()
        populateHeaders()
        self.tableView.delegate = self
        self.tableView.dataSource = self
        tableView.reloadData()
        tableContainer.documentView = tableView
        tableContainer.hasVerticalScroller = true

    }

}

extension TableView: NSTableViewDelegate, NSTableViewDataSource {
    func numberOfRows(in tableView: NSTableView) -> Int {
        return csvArray.count
    }
    func tableView(_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {
        var result:NSTableCellView
        result = tableView.makeView(withIdentifier: (tableColumn?.identifier)!, owner: self) as! NSTableCellView
        result.textField?.stringValue = csvArray[row][(tableColumn?.identifier.rawValue)!]!
        print("hi")
        return result
    }
    func tableView(_ tableView: NSTableView, shouldSelectRow row: Int) -> Bool {
        return true
    }


}

No Errors, the above code runs. Just need a way to import rows.


Solution

  • You are using a wrong table view DataSource delegate method. Use the tableView(_:objectValueFor:row:) delegate method for the cell-based table.

    func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
        let dict = csvArray[row]
        if ((tableColumn?.identifier)!.rawValue == "firstColumn") {
            return dict["whatever"]
        }
        else if ((tableColumn?.identifier)!.rawValue == "secondColumn") {
            return dict["whatever"]
        }
        ...
        ...
    }
    

    I don't know the exact column ID. Enter an ID for each column under the identity inspector.