Ken,
Thank you for the well-expressed response.  I understand both options as you've 
explained them and will try them both to see which ones I end up having a 
better feel for.  I may have to go for the second example as I think that it 
will get executed in a more deterministic order earlier - which is something 
that I will need to be reasonably assured of as the 'selectedWidget' value is 
one that is used by other KVO-triggered actions and that therefore lack of 
guaranteed order of setting can end up causing me problems.

On Friday, October 09, 2009, at 11:57PM, "Ken Thomases" <k...@codeweavers.com> 
wrote:
>On Oct 9, 2009, at 5:08 PM, A B wrote:
>
>> Is there a way to bind an ivar to the currently selected object of a  
>> list which is being represented in an NSTableView via bindings?   
>> Unfortunately there does not seem to be a "selectedObject" key  
>> (though there is one for "selectedObjects").  Binding to the  
>> controller's "selection" doesn't really work as I'd expect and even  
>> if it did, I'd only be getting back a proxy object - which negates  
>> the purpose for which I want to use it, which is to call methods on  
>> the object.  I had put in a hack which observes changes in  
>> selection, gets the selectedObjects list, checks for a count > 0,  
>> grabs the first and stuffs it into the ivar, etc. but not only does  
>> that feel really hackish, but doesn't always work.
>>
>> This would seem to be a pretty simple thing to want to do (i.e.  
>> present a list of objects, do things to/with the currently selected  
>> object) but I'm at somewhat of a loss to understand what I'm doing  
>> wrong.
>
>There's something just like this for NSPopUpButton.  You bind its  
>'content' (and possibly 'contentObjects') binding to an indexed  
>collection property of the controller.  Then you bind its  
>'selectedObject' binding to a to-one property of the controller.  When  
>the pop-up is first set up, it displays the selected object as  
>originally set on the controller's to-one property.  Then, as the user  
>selects items from the pop-up, the newly selected object is passed to  
>the setter for that to-one property.
>
>Strangely, there's nothing quite like that for NSArrayController.
>
>I think the best you can do is to bind the array controller's  
>selectionIndexes binding to an attribute of your coordinating  
>controller.  (For illustration purposes, I'll call this attribute  
>property "selectedWidgetIndexes".)  Then that coordinating controller  
>can have a "selectedWidget" to-one property which is set up to reflect  
>the object which is selected in the array controller.
>
>One way is to make the selectedWidget property computed-on-the-fly  
>based on the selection indexes:
>
>+(NSSet*)keyPathsForValuesAffectingSelectedWidget
>{
>       return [NSSet setWithObject:@"selectedWidgetIndexes"];
>}
>
>-(Widget*)selectedWidget
>{
>       if (![self.selectedWidgetIndexes count])
>               return nil;
>       return [self.widgets objectAtIndex:[self.selectedWidgetIndexes  
>firstIndex]];
>}
>
>In this scenario, you don't actually have an ivar backing the  
>selectedWidget property.  It's completely based off of the  
>selectedWidgetIndexes property and the "widgets" to-many property.   
>(The widgets property is assumed to be the indexed collection property  
>that the array controller is representing.  The selectedWidgetIndexes  
>property can be a typical @synthesized copy property.)
>
>Another approach is to implement the setter for selectedWidgetIndexes  
>and use that to update the selectedWidget property directly.  In this  
>case, selectedWidget isn't computed on the fly, but is actually held  
>(cached) in an ivar:
>
>-(void)setSelectedWidgetIndexes(NSIndexSet*)newSelectedWidgetIndexes
>{
>       if (![selectedWidgetIndexes isEqual:newSelectedWidgetIndexes])
>       {
>               [selectedWidgetIndexes release];
>               selectedWidgetIndexes = [newSelectedWidgetIndexes copy];
>               if ([selectedWidgetIndexes count])
>                       self.selectedWidget = [self.widgets objectAtIndex: 
>[selectedWidgetIndexes firstIndex]];
>               else
>                       self.selectedWidget = nil;
>       }
>}
>
>You don't need +keyPathsForValuesAffectingSelectedWidget since you're  
>going through the setter for the selectedWidget property.  The  
>selectedWidget property can be a typical @synthesized retain property.
>
>By the way, notice that all of this discussion is in terms of the  
>array controller and the coordinating controller.  No mention of the  
>table view because it's not directly relevant.  The MVC design pattern  
>in action.  ;)
>
>Regards,
>Ken
>
>
>
_______________________________________________

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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

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

Reply via email to