On Aug 2, 2012, at 10:16 PM, Erik Stainsby <erik.stain...@roaringsky.ca> wrote:

> 
> 
> I do so wish there was a Complete Idiot's Guide to Cocoa Table Bindings … The 
> very flexibility which I know must be their great virtue tends to obscure the 
> clear path from my sight more often than not.  Forest, trees, trees, forest … 
> Oh! Something shiny! 

Bindings are an 80% solution—that is, they usually get you 80% of the way there 
and then you have to throw them out and start over with the data source based 
approach. :)

> 
> So tonight I have an NSArrayController (RSTableArrayController) which I have 
> populated with dictionary objects of the form:
> 
> [self.content addObject:[NSDictionary dictionaryWithObjects: [NSArray 
> arrayWithObjects: key, [mvo valueForKey:key],nil] forKeys:[NSArray 
> arrayWithObjects:@"label",@"value",nil]]];
> 
> 
> 
> For this simple two column data I have a two column table, using Table View 
> Cells (I'm going to have visual objects in place of the 'label' later on).

You should consider using a view-based table view if you're targeting 10.7 or 
later. They're so much nicer!

> I have set the identifier for the tableView columns very imaginatively to 
> "label", and "value". 
> The array controller is also < NSTableViewDataSource, NSTableViewDelegate >. 
> I have implemented the following two delegate methods:
> 
> - (NSInteger)    numberOfRowsInTableView:(NSTableView *)aTableView {
>    return self.content.count;
> }
> 
> - (id)            tableView:(NSTableView *)aTableView    
> objectValueForTableColumn:(NSTableColumn *)tableColumn 
> row:(NSInteger)rowIndex {
>    NSString * identifier = [tableColumn identifier];
>    NSDictionary * dict = [self.content objectAtIndex:rowIndex];
>    NSLog(@"%s- [%04d] %@: %@", __PRETTY_FUNCTION__, __LINE__, 
> identifier,[dict valueForKey:identifier]);
>    return [dict valueForKey:identifier];
> }

The whole point of bindings is that you don't implement these two methods. 
They're data source methods, not delegate methods, and their functionality is 
completely supplanted by bindings.

> 
> In the nib, I have an ArrayController object of the class described above 
> RSTableArrayController. It is wired up as the delegate and dataSource for the 
> tableView. 
> 
> 
> And here is where I get lost time and again, tracing the appropriate path to 
> the content and it's constituent data parts and binding them to the 
> appropriate element in the tableView.
> 
> » Scroll View
>    » Table View
>        » Table Column
>            » Table Cell View
>                » Static Text
>                     Text Field Cell

If you want to use bindings, first delete your implementations of the above 
methods.

Then, how you proceed depends on whether you're using a view-based table view.

For a cell-based table view: bind all of your table columns' Content bindings 
to the arrangedObjects key of your controller. Then bind the Value binding of 
the text field cell in each column to the appropriate keypath of your 
controller's arrangedObjects. So the text field cell in the label column will 
be bound to your controller object with a controller key of arrangedObjects and 
a model keypath of "label". Similarly for the value column.

If the Content bindings of a cell-based table view are all bound to the same 
keypath of the same controller, the cell-based table view automatically binds 
its Content binding to the same keypath of the same controller. You don't need 
to set this binding up yourself, but it's good to know what it's for.

View based table view bindings make a lot more sense. You bind the table view's 
Content binding to the arrangedObjects of your array controller (just once, 
rather than once per column). Then you bind each of the views inside each 
column's NSTableCellView to the appropriate keypath of their enclosing 
NSTableCellView's objectValue property.

For both view-based and cell-based table views, if the table view's content 
binding is set (whether explicitly or automatically) the table view 
automatically binds its selectionIndexes and sortDescriptors bindings to the 
appropriate keys of the controller its Content binding is bound to.

To recap, for cell-based table views:
[LabelColumn].content => [ArrayController].arrangedObjects
[LabelColumn.cell].value => [ArrayController].arrangedObjects.label
[ValueColumn].content => [ArrayController].arrangedObjects
[ValueColumn.cell] => [ArrayController].arrangedObjects.value

For view-based table views:
[Table View].content => [ArrayController].arrangedObjects
[LabelColumnCellView.textField].value => [LabelColumnCellView].objectValue.label
[ValueColumnCellView.textField].value => [ValueColumnCellView].objectValue.value

View-based table views have the advantage that even if you decide to revert to 
standard NSTableDataSource methods for providing the data to your table view, 
you can still use bindings *within* your NSTableCellViews to provide the data 
to your text fields.

--Kyle Sluder

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to