views:

183

answers:

4

Hi,

I've been attempting this for two days, and constantly running into dead ends.

I've been through Aaron Hillegass's Cocoa Programming for MAC OS X, and done all the relevant exercises dealing with NSTableview and mutable arrays, and I have been attempting to modify them to suit my needs.

However none of them seem to be using an array with objects as a data source, it seems to use the tableview as the datasource.

I'm trying to implement Jonas Jongejan's "reworking" of my code here, with a Cocoa front end to display the results.

Any pointers or suggestions I know this should be simple, but I'm lost in the wilderness here.

I can populate the table by setting the array

+2  A: 

Apple has a whole guide for Table View Programming so I suggest you start with the Using a Table Data Source section of the that guide.

willcodejavaforfood
+1  A: 

On the iPhone (I know you're talking about Mac, but maybe this could help) you have to use delegation for loading a tableView. It asks for a cell and you use your array to fill-in the data where needed. I'm not sure if this works for the Mac, but it'd be worth looking into.

Maybe set dataSource to self and use those delegate methods to access your array based on the row and column #

Ryan Sullivan
@willcodejavaforfood's answer is for the iPhone but you can follow that link to see what I mean
Ryan Sullivan
Oops, I got iPhones on my brain :)
willcodejavaforfood
+3  A: 

It's pretty simple really, once you get to understand it (of course!). You can't use an NSArray directly as a table source. You need to either create a custom object that implements NSTableViewDataSource or implement that protocol in some existing class - usually a controller. If you use Xcode to create a standard document based application, the document controller class - (it will be called MyDocument) is a good class to use.

You need to implement at least these two methods:

– numberOfRowsInTableView:
– tableView:objectValueForTableColumn:row:

If you have a mutable array whose values you'd like to use in a table view with one column, something like the following should do as a start:

– numberOfRowsInTableView: (NSTableView*) aTableView
{
    return [myMutableArray count];
}

– tableView: (NSTableView*) aTableView objectValueForTableColumn: (NSTableColumn *)aTableColum row: (NSInteger)rowIndex
{
    return [myMutableArray objectAtIndex: rowIndex];
}

It has just occurred to me that you could add the above two methods as a category to NSArray replacing myMutableArray with self and then you can use an array as a data source.


Anyway, with a mutable array, it is important that any time you change it, you need to let the table view know it has been changed, so you need to send the table view -reloadData.


If your table view has more than one column and you want to populate it with properties of objects in your array, there's a trick you can do to make it easier for yourself. Let's say the objects in your array are instances of a class called Person with two methods defined:

-(NSString*) givenName;
-(NSString*) familyName;

and you want your table view to have a column for each of those, you can set the identifier property of each column to the name of the property in Person that that column displays and use something like the following:

– tableView: (NSTableView*) aTableView objectValueForTableColumn: (NSTableColumn *)aTableColum row: (NSInteger)rowIndex
{
    Person* item = [myMutableArray objectAtIndex: rowIndex];
    return [item valueForKey: [tableColumn identifier]];
}

If you replace valueForKey: with valueForKeyPath: and your Person class also has the following methods:

-(Person*) mother;
-(Person*) father;
-(NSString*) fullName;  // concatenation of given name and family name

you can add table columns with identifiers like: father.fullName or mother.familyName and the values will be automatically populated.

JeremyP
+1  A: 

You could go the datasource route and do all of the heavy lifting yourself, or you could let bindings do all the heavy lifting for you. Add an NSArrayController to the nib file that has the table view in it. Make sure that the File's Owner of the nib is set to the same class that has the mutable array in it. Bind the contentArray of the array controller to File's Owner.myMutableArray. For each column bind Value to the array controller arrangedObjects and add the appropriate key path. This will allow you to get things like user sorting for free if you ever need it.

theMikeSwan