Reputation: 137
I have a view-based NSTableView where all the cells are editable. I need to refresh the data from the model every time the user modifies a textField from the view.
All the doc I find is related to the cell-based NSTableView.
Does anyone have a clue about this?
EDIT:
I'm using data source to populate this NSTableView.
This is the code of the Controller of the NSTableView
class ViewController: NSViewController, NSTableViewDelegate, NSTableViewDataSource {
@IBOutlet var globalView: NSView!
@IBOutlet var songsTableView: NSTableView!
var tableContents = NSMutableArray()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
for (song) in songManager.songs {
var obj = Dictionary<String,String>()
obj["title"] = song.title
obj["artist"] = song.artist
tableContents.addObject(obj)
}
songsTableView.reloadData()
}
func numberOfRowsInTableView(tableView: NSTableView) -> Int {
return tableContents.count
}
func tableView(tableView: NSTableView, viewForTableColumn tableColumn: NSTableColumn?, row: Int) -> NSView?{
var obj = tableContents[row] as Dictionary<String,String>
let column = tableColumn?.identifier
var cellView = tableView.makeViewWithIdentifier(column!, owner: self) as NSTableCellView
if column == "title" {
cellView.textField?.stringValue = obj["title"]!
}
if column == "artist" {
cellView.textField?.stringValue = obj["artist"]!
}
cellView.textField?.editable = true
return cellView
}
}
And this is the code of the class that manages the data.
var songManager = SongManager()
struct song {
var title = "No name"
var artist = "No artist"
}
class SongManager: NSObject {
var songs = [song]()
func addSong(title: String, artist: String) {
songs.append(song(title: title, artist: artist))
}
}
I have not touched the row that the storyboard creates by default, so I guess it contains a single NSTextField.
I get to display the data, but cannot detect when the user tried to modify a textfield.
Upvotes: 0
Views: 226
Reputation: 90581
Given how things are currently set up, the simplest approach is probably to connect the text field's action selector to an action method on a target, such as your controller. You can do that in IB or in your tableView(_:viewForTableColumn:row:)
method.
In that action method, you can call songsTableView.rowForView(sender)
to determine which row was edited. Each column's text field would have a different action method, such as changeTitle()
or changeArtist()
, so that you know which column was edited. (You could also use songsTableView.columnForView(sender)
, then get the table column by using the index in songsTableView.tableColumns[col]
, and checking the returned column's identifier
. For that, you would assign specific identifiers to the columns rather than letting IB assign them automatically.)
Once you have the row, you look up your dictionary using var obj = tableContents[row] as Dictionary<String,String>
and set the value for the key appropriate to the action method (or column identifier) to the sender's stringValue
.
Upvotes: 0