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 ([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:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com
This email sent to [email protected]