Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Thomas Harte

macrumors 6502
Original poster
Nov 30, 2005
400
4
I am someone with past experience of C++ and MFC who is trying to get started with Objective-C and Cocoa development. I have some books ordered to help me, but they haven't turned up yet, so I'm stuck trying to figure stuff out from the XCode help and http://developer.apple.com/documentation/Cocoa/. I did the Currency Converter tutorial and now am sort of wandering the API around aimlessly.

Today I am trying to make a decent stab at a NSTableView. I have added an NSTableView to my .nib, and set my controller as a dataSource. I have added the two methods numberOfRowsInTableView and what I guess could be called objectValueForTableColumn to my controller and I am able to populate the NSTableView by returning sensible results from those two methods. I am returning NSStrings for objectValueForTableColumn.

I have two questions. Firstly, what is the "correct" way to use the value passed as an (NSTableColumn *) to objectValueForTableColumn? At the minute I'm just doing [[tableColumn headerCell] stringValue] and comparing that to what I know are the column headers. That works, but strikes me as a very roundabout way of doing things and prone to localisation problems.

Secondly, how do I stop my NSTableView from being editable? What I really want is to receive a message on a row double click that will be responded to by actions in my model class. I have not implemented setObjectValue, which I thought would be enough to prevent editing but it doesn't seem to be. I want dragging and dropping so I need to implement validateDrop and forDraggedRowsWithIndexes, but I haven't done that yet.

Thanks in advance, and sorry for asking what are probably very basic questions that will have easy and easily discoverable answers once I have books.
 

HexMonkey

Administrator emeritus
Feb 5, 2004
2,240
504
New Zealand
Thomas Harte said:
Firstly, what is the "correct" way to use the value passed as an (NSTableColumn *) to objectValueForTableColumn? At the minute I'm just doing [[tableColumn headerCell] stringValue] and comparing that to what I know are the column headers. That works, but strikes me as a very roundabout way of doing things and prone to localisation problems.

You could use [tableColumn identifier] instead. The identifier is set in Interface Builder in the same place as the header title, and it needn't be localised.

Thomas Harte said:
Secondly, how do I stop my NSTableView from being editable? What I really want is to receive a message on a row double click that will be responded to by actions in my model class. I have not implemented setObjectValue, which I thought would be enough to prevent editing but it doesn't seem to be.

To prevent the cells from being editable, select each table column in Interface Builder and uncheck the "Editable" attribute in the inspector.

To handle a double click, add the following code in your awakeFromNib method:
Code:
[tableView setTarget:self];
[tableView setDoubleAction:@selector(doubleClickInTable:)];

The doubleClickInTable method (call it anything you want) would be implemented as follows:

Code:
- (void)doubleClickInTable:(id)sender
{
	int rowIndex = [sender selectedRow]; //Use selectedRowIndexes if you're supporting multiple selection
	
	//Handle the double click
}
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
I would recommend looking at Bindings instead of a datasource but we'll skip that for now!

Set a tag for each header in Interface Builder and then use [tableColumn tag]==0 (or whatever the tag value is: they are ints). The tag won't change on localization. (and int comparisons are cheaper than NSString). Edit: beaten to it and with the correct answer too: columns don't seem to have tags :(

Per column (double click on the column until it highlights) there is an editable attribute in Interface Builder. Use that to stop it being editable :D

Any more questions?
 

Thomas Harte

macrumors 6502
Original poster
Nov 30, 2005
400
4
HexMonkey said:
To handle a double click, add the following code in your awakeFromNib method: ...
I have implemented it exactly as you suggest, but I seem to be getting single clicks as well. Is there anything I can do about that?
robbieduncan said:
I would recommend looking at Bindings instead of a datasource but we'll skip that for now!
We'll have to as I haven't yet figured out anything whatsoever about Bindings! I'll make a note to check that topic out as soon as I have some nice tangible documentation though.
HexMonkey said:
You could use [tableColumn identifier] instead.
robbieduncan said:
Set a tag for each header in Interface Builder and then use [tableColumn tag]==0 (or whatever the tag value is: they are ints)
I've gone with naming my columns as numbers and the following:

int column = [[tableColumn identifier] UTF8String][0] - '0';

I'm only planning on three columns, so I don't have to worry about moving on from '9' to ';' or anything like that.
 

robbieduncan

Moderator emeritus
Jul 24, 2002
25,611
893
Harrogate
Thomas Harte said:
We'll have to as I haven't yet figured out anything whatsoever about Bindings! I'll make a note to check that topic out as soon as I have some nice tangible documentation though.

Start off with the Apple Documentation.

That will probably leave you dazed and confused so then take a look at a nice easy introductory tutorial.

Now you are probably beginning to get an understanding and some clear examples will help.
 

HexMonkey

Administrator emeritus
Feb 5, 2004
2,240
504
New Zealand
Thomas Harte said:
I have implemented it exactly as you suggest, but I seem to be getting single clicks as well. Is there anything I can do about that?

That's strange, the only way that happens for me is if the table view also has an action (as well as a double action). Try adding the code:
Code:
[tableView setAction:nil];
to the end of your awakeFromNib method and see if it fixes it. If it does, check your connections in Interface Builder and make sure you're not calling setAction elsewhere in your code.
 

Thomas Harte

macrumors 6502
Original poster
Nov 30, 2005
400
4
robbieduncan said:
Start off with the Apple Documentation.
Although I am building on 10.4, I want to retain compatibility with 10.2 and 10.3 so I guess I can't use bindings in this project. It's actually really trivial on the code side and something I'm sure anyone with good Cocoa sense could knock up in half an afternoon. If it gets too much for me I'll just go back to the tutorials rather than asking stupid questions here...
HexMonkey said:
That's strange, the only way that happens for me is if the table view also has an action (as well as a double action). Try adding the code: ...
Interestingly that stopped the response to double clicks, so I guess I must have a connection set up in Interface Builder that I've just forgotten about. I can't find anything, but I'm still not 100% confident with that corner of the developer tools having just been using XCode to do the normal platform neutral stuff with SDL and so on until now.

Anyway, I just wanted to say thanks to both of you for the help. Thanks!
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.