(reposted because of an apparent bounce)
On Aug 2, 2012, at 22:16 , Erik Stainsby <[email protected]> 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!
I don't know that you have a problem with bindings as such. I think your
problems are mainly with NSArrayController. On top of that, I think you might
have some terminology wrong (possibly just typos).
> So tonight I have an NSArrayController (RSTableArrayController)
Ugh, subclassing an array controller (any NSController, really) is going to
make you unhappy, eventually.
> 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]]];
Ugh, again, sorry to say. There are several warning flags here.
-- It's rarely easier to use a NSDictionary instead of define a custom class. A
dictionary is a better solution only when the data objects have properties that
cannot be determined until run time. If you know the properties of your data,
step up and write the custom class right from the beginning. It'll be easier to
write your code, and easier to debug.
-- By doing something like the above in an array controller subclass, you've
muddied your MVC design pattern. The array of dictionaries *is* your data model
-- or perhaps is just part of the data model -- but exposing its internal
structural details, here in a mediating controller, is about 2 controllers away
from where your data model really should be.
-- This code is not KVO compliant. This may not matter initially, if it happens
before the view gets displayed, but it suggests you're going to think of your
data (self.content) as an array, rather than as an indexed property of a data
model object, and I'll bet you run into KVO compliance problems later.
> 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).
> 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];
> }
>
> 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.
The data source code seems fine (though I didn't peer at it line by line), but
I think it's in the wrong place. The more usual placement in a window
controller is better than putting it in the array controller. The less code
references you have to the array controller, the easier your app will be write
and debug. (Best of all: don't even define an outlet to the array controller.
Unfortunately, that's not always feasible, but I believe it's always desirable.)
> 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
Do you mean "Table View Cell"? These days, "Table Cell View" means something
quite different.
> » Static Text
> Text Field Cell
I'm not sure where these levels come from. In IB, the next level down from
"Table Column" is some kind of cell, and there's nothing else. Did you perhaps
create a view-based table instead of a cell-based table? Did you really want a
view-based table (in which case you're implementing the wrong data source
methods)?
> Given that the delegate method is called -[tableView:
> objectValueForTableColumn: row:] I should expect to bind the
> arrayController's objectValue
I'm not sure what you mean here. Array controllers don't have an "objectValue"
property or binding. Array controller bindings have names like "contentObject"
or "contentArray".
> in the Bindings Inspector to the ?node? in the object browser.
The normal thing is to bind the table column's "value" binding to the array
controller's "arrangedObjects" controller key, specifying the model key that
represents the property you want to display -- "label" in this case.
You *can* bind properties of the cell itself, but since certain properties
bound from the table column are propagated *down* to the cell (when the cell
for the column is requested) and certain cell properties are overridden (when
the cell is prepared for use in a particular row/column context), things you do
to the cell may get overridden.
_______________________________________________
Cocoa-dev mailing list ([email protected])
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 [email protected]