Changing the number of columns in a table view

thanks to Shane’s book I made quick start learning ASOC, but right now I’m running into a problem I can’t solve myself: how to add/remove columns in a table view programmatically (rather than using binding in IB). For example, I want to read data from an Excel worksheet and create - during run-time - the exact number of columns in the table view that were present in the original Excel table. Any help is appreciated.


Model: MacPro
Browser: Safari 533.19.4
Operating System: Mac OS X (10.6)


I haven’t done it myself yet, but I believe it is feasible this way (anyone, please correct me if I’m wrong):

Inside a repeat loop (based on the number of columns in the Excel document), first create a new NSTableColumn object this way:

tell current application's NSTableColumn to set newTableColumn to initWithIdentifier_("theIdentifier")

the “theIdentifier” is only an example, use whatever you need instead.

then set it’s various parameters with methods like setHeaderCell:, setHeaderToolTip:, setHidden: (never know!), setEditable:, setWidth:, setMaxWidth: and setMinWidth:. There is probably a few others that you may need, they all are under the NSTableColumn Class Reference in the docs. Here’s how for example to set it’s current width:

newTableColumn's setWidth_(100)

Then add the newly create column to your pre-existing table view:

mainTableView's addTableColumn_(newTableColumn)

this will add it as the last column in the table view according to the docs.

The rest, I think you will be able to figure it out on your own. :slight_smile:


Browser: Safari 531.22.7
Operating System: Mac OS X (10.6)

Just create a new column and add it:

		theTable's addTableColumn_(current application's NSTableColumn's alloc()'s init())

But you might find it easier to start of with a bunch and then either delete or hide those you don’t need.

Shane, your way is more direct I admit, but then if we need to set all the parameters of every table column, can it be done afterwards? Maybe a repeat loop through all the table columns and use the methods I talked about in my previous post?

Browser: Safari 531.22.7
Operating System: Mac OS X (10.6)

First, you should never call dealloc(), regardless – it’s for the system to call. Second, unless you specifically turn garbage collection off, it is on for ASObjC apps, so there shouldn’t be any need to use release(). If you do use release() in a GC ASObjC app, all it does is waste time…

Thanks, that clarifies my doubts about this.

Browser: Safari 531.22.7
Operating System: Mac OS X (10.6)

Yes, you would need to do something like that – which is why I suggested just setting them up first and deleting unnecessary ones later, to simplify things.

Hi. Thanks Leon, Shane…

Leon’s method works if one adds the alloc() method (this was suggested by another poster, but the post somehow disappeared…):

tell current application’s NSTableColumn to set newTableColumn to alloc()'s initWithIdentifier_(“theIdentifier”)
newTableColumn’s setWidth_(500)
my MyTable’s addTableColumn_(newTableColumn)

Shane’s method work as well…

The next question is:

  • how to set the column title
  • how to link/bind the new column to an array controller

Thanks for your help!!


Well, as it is mentioned in the docs in the initWithIdentifier: method description:

Thus I would think that this would do the trick after initializing the column:

newTableColumn's headerCell()'s setStringValue_("Title")

As for the binding question, without being too certain, I’d say it be best to use a data source with corresponding identifiers and connect that data source to the table view instead. I’m not too sure how to programmatically bind items like in IB, not even sure it is possible. Someone else might know the answer.

Sorry I can’t be of more help! :slight_smile:

Browser: Safari 531.22.7
Operating System: Mac OS X (10.6)

Wow, I thought I’ve tried every permutation of the command you mentioned and always got an error, your suggestions works right away!

Thanks again…

…and coupling to the datasource using the identifier works as well, great tip!

I’m posting this reply again – for the second time in two days one of my posts has disappeared from the board.
I made a sample program to programmatically implement bindings to populate a tableView. I created a small array that holds the data for the table, and in IB I connected col1 and col2 to the two columns in the table. I think that it’s still probably better to do this in IB, but if you need to do it in code, this works:

script BindingsAppDelegate
	property parent : class "NSObject"
	property theData : missing value
	property col1 : missing value
	property col2 : missing value
	on applicationWillFinishLaunching_(aNotification)
		set my theData to current application's NSMutableArray's arrayWithArray_({{key1:"Hello", key2:"Goodbye"}, {key1:"Thanks", key2:"You're welcome"}})
		set controller to current application's NSArrayController's alloc()'s init()
		controller's bind_toObject_withKeyPath_options_("contentArray", me, "theData", missing value)
		col1's bind_toObject_withKeyPath_options_("value", controller, "arrangedObjects.key1", missing value)
		col2's bind_toObject_withKeyPath_options_("value", controller, "arrangedObjects.key2", missing value)
	end applicationWillFinishLaunching_
end script


I’ve already sent a message to the board’s moderators, they are well aware of it it seems and are investigating.

Browser: Safari 6533.18.5
Operating System: Mac OS X (10.6)