how to input user data from a tableview

I have a varialbe length list of categories and I want the user to be able to set a budget for each category.


I do not want the values updated as the user edits but only when they hit a button.


I have an NSTableView that displays the category names in one column and the current budget values in the second column.


What I can't figure out is how to access the value for a given cell in the second column.


I'm using a view based NSTableView and I can get the view at column N, row I but I don't know how to get the text value being displayed the


Thanks for any help

Answered by trinko in 134258022

I figured out a work around. I used IB to have the tableviewcell send an action when editing was ended. in the action I filled in an array with the new values the user had entered. If the user didn't click the update button those changes weren't saved back into the data. But when the user clicks on the update button the values are put in the data.


Inelegent but it works.

You have a delegate function for tableView that just do this :


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

It gets data from the dataSource to display in the table


You have to set a unique identifier each column in IB : "name", "age"

You have your data source (an array with 2 columns) that stores your data: items[row] is an array (you could alos use a dictionary)


Here is from an excellent online tutorial (CocoaProgramming from AppleProgramming) an example

import Cocoa
class Person: NSObject {
    var name : String
    var age : Int

    override init() {
        self.name = String()
        self.name = "Yoda"
        self.age = 300
        super.init()
    }
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
    required convenience init?(coder decoder: NSCoder) {
        self.init()
        self.name = decoder.decodeObjectForKey("name") as! String
        self.age = decoder.decodeObjectForKey("age") as! Int
    }
}
/
extension Person: NSCoding {
    func encodeWithCoder(coder: NSCoder) {
        coder.encodeObject(self.name, forKey: "name")
        coder.encodeObject(Double(self.age), forKey: "age")
    }
}



and the controller


class TableViewController: NSObject, NSTableViewDataSource {
    @IBOutlet weak var tableView: NSTableView!
    var list : [Person]
  
     override init () {
        list = [Person]()
        super.init()
    }
  
    func numberOfRowsInTableView(tableView: NSTableView) -> Int {
        return list.count
    }
    func tableView(tableView: NSTableView, objectValueForTableColumn tableColumn: NSTableColumn?, row: Int) -> AnyObject? {
        let p = list[row]
        let identifier : String = (tableColumn?.identifier)!
        let s = p.valueForKey(identifier as String)
        return s
    }
  
    func tableView(tableView: NSTableView, setObjectValue object: AnyObject?, forTableColumn tableColumn: NSTableColumn?, row: Int) {
        let p = list[row]
        let identifier : String = (tableColumn?.identifier)!
        p.setValue(object, forKey: identifier as String)
        tableView.reloadData()
    }
  
   
    @IBAction func add(sender: NSButton) {
        let p = Person(name: "aName", age: 20)
        self.list.append(p)
        tableView.reloadData()
    }
  
    @IBAction func remove(sender: AnyObject) {
        let row = tableView.selectedRow
        tableView.abortEditing()   /
        if row >= 0 {
            list.removeAtIndex(row)
            tableView.reloadData()
        }
    }       
}

I'm not sure I made my problem clear


While I set the values in the table using the tableView method I'm allowing the user to change the values in the tableview by making the cells in the second column editable.


I want to know how to retrieve the new values the user has entered from the table.


I notice there are two versions of the tableView function. the first is called by the tableview to populate the cells.


I'm unclear as to how/when the second version of the function is called:



func tableView(tableView: NSTableView, setObjectValue object: AnyObject?, forTableColumn tableColumn: NSTableColumn?, row: Int) {


an example of how to get the value for row n, column i of a tableview would be appreciated.


Thanks for your help!

Accepted Answer

I figured out a work around. I used IB to have the tableviewcell send an action when editing was ended. in the action I filled in an array with the new values the user had entered. If the user didn't click the update button those changes weren't saved back into the data. But when the user clicks on the update button the values are put in the data.


Inelegent but it works.

For your information, setValue must not be used for view based :


View-based table views must not use the

tableView:setObjectValue:forTableColumn:row:
method for setting values. Instead the views must explicitly set the values for the fields, or use Cocoa bindings. Likewise, use target/action for editing. See Table View Programming Guide for Mac for more information on populating view-based and cell-based table views.

Another way to do it is to have 2 instances of your datastore:

- currentData, that tableView uses

- storedData, in which you copy the currentData when user validates ; this allows also to have a cancel, in which case you copy store back to current.

how to input user data from a tableview
 
 
Q