On Dec 12, 2009, at 10:35 PM, Gerriet M. Denkmann wrote:

> Well, not quite.
> As I stated in some previous post in this thread, the NSDictionaryController 
> (bound to "currentDictionary") fills an editable NSTableView.
> And if the user edits some key or value in this NSTableView the 
> NSDictionaryController does NOT update "currentDictionary", but replaces it 
> with another NSDictionary.

Forgot about that. Instead, I would recommend:

0. observe NSArrayController's "selectionIndex"
1. I am assuming that the observing object owns the array that is the content 
for the array controller. If not, then you need a reference to the owning 
object, used instead of "self" below. I am calling the content array 
"contentArray".
2. You will only have one property: "selectedDictionary", not an instance 
variable, but you implement the accessors yourself (see below)

observeValueForKeyPath tells you when the selection changes:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object 
change:(NSDictionary *)change context:(void *)context
{
    // if you have a specific context, you don't need to check the key name
    if( object == arrayController && context == kSelectedDictionary )
    {
        // when the selection changes, so does the selectedDictionary property.
        [self willChangeValueForKey:@"selectedDictionary"];
        [self didChangeValueForKey:@"selectedDictionary"];
    }
    else
    {
        [super observeValueForKeyPath:keyPath ofObject:object change:change 
context:context];
    }
}


Implement selectedDictionary accessors:

- (NSDictionary *)selectedDictionary
{
    NSArray *arrangedObjects = [ arrayController arrangedObjects ];
    NSUInteger selectedIndex = [arrayController selectedIndex];
    if( selectedIndex == NSNotFound ) return nil;
    return [arrangedObjects objectAtIndex: selectedIndex];
}

- (void)setSelectedDictionary:(NSDictionary *)newDictionary
{
    if( newDictionary != selectedDictionary )
    {
        // if you implemented indexed accessors, you could use the 
corresponding method instead
        NSMutableArray *mutableProxy = [self 
mutableArrayValueForKey:@"contentArray"];
        // shouldn't assume that the array orders are the same, so find it
        NSUInteger sourceIndex = [mutableProxy indexOfObject: 
selectedDictionary];
        [mutableProxy replaceObjectAtIndex: sourceIndex withObject: 
newDictionary];
    }
}

Written in Mail, and untested, so caveat emptor.

> So I also have to do:
> 5. observe "currentDictionary" and if it is no longer the original value, 
> delete the originalDictionary from the arrayController and insert the 
> currentDictionary.
> 
> 
> Here is the complete class (I renamed your "currentDictionary" to 
> "selectedDictionary"):
> (and if you find any more silly things, please point them out!)
> 
> 
> #import "Test_Dict_EditAppDelegate.h"
> 
> static NSString *kSelectedDictionary  = @"selectedDictionary";
> static NSString *kSelectedObjects             = @"selectedObjects";
> 
> @implementation Test_Dict_EditAppDelegate
> 
> @synthesize originalDictionary;
> @synthesize selectedDictionary;
> 
> - (void)arraySelectionHasChanged;
> {
>       NSArray *selectedObjects = [ arrayController selectedObjects ]; 
>       NSMutableDictionary *currentDictionary = [ selectedObjects count ] == 1 
> ? [ selectedObjects lastObject ] : nil; 
>       self.originalDictionary = currentDictionary;
>       self.selectedDictionary = currentDictionary;
> }
> 
> 
> - (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
> {
>       [ self  addObserver:    self  
>                       forKeyPath:     kSelectedDictionary 
>                       options:                0 
>                       context:                kSelectedDictionary
>       ];
> 
>       [ arrayController       addObserver:    self  
>                                               forKeyPath:     
> kSelectedObjects 
>                                               options:                0 
>                                               context:                
> kSelectedObjects
>       ];
>       
>       [ self arraySelectionHasChanged ];
> }
> 
> - (void)observeValueForKeyPath:(NSString *)keyPath  ofObject:(id)object  
> change:(NSDictionary *)change context:(void *)context
> {
>       if              (       object == self  &&  context == 
> kSelectedDictionary  &&  
>                               [ keyPath isEqualToString: kSelectedDictionary 
> ] 
>                       )
>       {
>               if ( selectedDictionary != nil  &&  selectedDictionary != 
> originalDictionary )  //      reinsert
>               {
>                       NSArray *arrangedObjects = [ arrayController 
> arrangedObjects ];                 
>                       NSUInteger index = [ arrangedObjects indexOfObject: 
> originalDictionary ];
>                       if ( index == NSNotFound ) ...  //      error
> 
>                       [ arrayController insertObject: selectedDictionary  
> atArrangedObjectIndex: index ];
>                       [ arrayController removeObjectAtArrangedObjectIndex: 
> index + 1 ];
> 
>                       self.originalDictionary = selectedDictionary;
>               };
>       }
>       else if (       object == arrayController  &&  context == 
> kSelectedObjects  &&  
>                               [ keyPath isEqualToString: kSelectedObjects ] 
>                       )
>       {
>               [ self arraySelectionHasChanged ];
>       }
>       else
>       {
>               [super observeValueForKeyPath:keyPath ofObject:object 
> change:change context:context];
>       };
> }


Keary Suska
Esoteritech, Inc.
"Demystifying technology for your home or business"

_______________________________________________

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