As we discussed in a former topic how to coloring text in a table’s cell the delegate tableView_willDisplayCell_forTableColumn_row_ works well.
Exept the count of data cells is not to much. Then the app hangs every time the user makes a key stroke.
An unsatisfactorily situation.
So I’m going to coloring the cells myself by a button (or menu item).
That led to a surprising result: I can read out the content of every cell but can’t set the individual text color.
on bTableColor_(sender)
set rowCount to numberOfRowsInTableView_(aTableView)
set theColumn to aTableView's columnWithIdentifier_("myIdentifier")
aTableView's beginUpdates()
repeat with i from 1 to rowCount
set theCell to aTableView's preparedCellAtColumn_row_(theColumn,i-1)
set cellContent to theCell's stringValue()
if cellContent is in {"4", "3", "2", "1"} then
set aColor to myGreenColor --colorClass's greenColor
else
set aColor to colorClass's redColor
end if
log theCell -- always the same cell
log cellContent -- correct content
log aColor -- set correctly
theCell's setTextColor_(aColor)
end repeat
aTableView's endUpdates()
end bTableColor_
The result: the whole column is set to the color who is set at the end of the script.
reloadDataForRowIndexes:columnIndexes: reloads the data as it says, so aTableView’s reloadData() should do the same, but it doesn’t. Only the whole column ist colored in the same color.
It’s a pity!
I don’t know how it should work. tableView:willDisplayCell:forTableColumn:row: is bound by the table as a delegate. The handler checks all cells in every column and every row in every table view (in my case there are three and ca. 400 cells for every table); that lasts for a very long time, even the handler is empty (only on and end).
normally you send a reloadData() message to the table view which causes the whole table to be redrawn.
The reloadDataForRowIndexes:columnIndexes: method calls tableView:willDisplayCell:forTableColumn:row: only for the specified rows / columns which is much faster than redrawing the whole table
In tableView_willDisplayCell_forTableColumn_row_(aTableView, acell, aColumn, aRow) is no need to reload the table. The ‘system’ do it permanently by itself. How can I have an Influence to that?
Would it be possible to use a completely different approach – that is to have your data be NSAttributedStrings, so that the color would be an intrinsic part of the data instead of using the table view methods to provide the color. This would depend on how you are getting the data into your table, and how you are using the data. I’m sure it’s possible this way, I’ve done it with a 50,000 row table, but it might not be the most efficient way depending on what you need to do with the data.
Oh god!! My script has more than 5000 lines, the tables are communicating to each other and compare values. As I read in Doc’s NSAttributedStrings in rush comparison is not easy. My tables are handled via data sources and I think the new approach would strech my possibilities too far.
And: Coloring the cells in a different way would only be an additional feature in my app. It is not really necessary.
If your requirements are simple, you should be able to edit the sample Objective-C code, rather than rewriting it in AS. That would help with speed significantly.
I tried out a transformer written in ASOC, and at least with my example (which converts numbers to attributed strings with colors that depend on the value of the number), and using bindings, the value transformer did not seem to take any time at all. I created a half million member array of random numbers (that part I did do in Objective-C), that was used as the content for my table, and it only took 2 seconds to populate the table whether or not the value transformer was present.