I'd like to expose NSTableView's option usesAlternatingRowBackgroundColors as a
settable preference in my app's preferences window. "Easy, just use a binding",
I thought before I realized that NSTableView does not expose this setting via
bindings, neither using IB nor programatically.
I found two solutions to this problem, both of them more or less
unsatisfactory. In my NSTableView's subclass +initialize method I register the
default value
#define defaults [NSUserDefaults standardUserDefaults]
NSDictionary *appDefaults = [NSDictionary
dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES],
@"usesAlternatingRowBackgroundColors", nil];
[defaults registerDefaults:appDefaults];
whereas in -awakeFromNib I use the value stored in the user defaults
#define defaultValues [[NSUserDefaultsController sharedUserDefaultsController]
values]
[self setUsesAlternatingRowBackgroundColors:[[defaultValues
valueForKey:@"usesAlternatingRowBackgroundColors"] boolValue]];
In my preferences panel I have bound the value key of a checkbox to the shared
user defaults controller.
This is all pretty standard and it works so far.
1. Solution
In my preferences panel's controller I have defined the following action method
for the check box
- (IBAction)clickAlternatingRowsCheckbox:(id)sender{
NSInteger checkboxState = [sender state];
if (checkboxState == NSOffState) {
[myTableView setUsesAlternatingRowBackgroundColors:NO];
}
else if (checkboxState == NSOnState) {
[myTableView setUsesAlternatingRowBackgroundColors:YES];
}
}
This solution saves the setting to the user defaults via bindings, but works
only when the value is changed via the GUI and breaks MVC - the preferences
controller should better not be hooked up with a view used elsewhere in the
app. To avoid this, I deviced a
2. Solution
I set the controller of my NSTableView's subclass as KVO observer of the key in
the sharedUserDefaultsController:
#define theDefaultsController [NSUserDefaultsController
sharedUserDefaultsController]
[theDefaultsController addObserver:self
forKeyPath:@"values.usesAlternatingRowBackgroundColors" options:
NSKeyValueObservingOptionNew context:NULL];
The controller handles the observation like this
- (void) observeValueForKeyPath: (NSString *) keyPath
ofObject: (id) object
change: (NSDictionary *) change
context: (void *) context
{
if ( [keyPath isEqualToString:@"values.usesAlternatingRowBackgroundColors"]
) {
//NSLog(@"%@", [change objectForKey:NSKeyValueChangeNewKey]);
[self.myTableView
setUsesAlternatingRowBackgroundColors:[[theDefaultsController
valueForKeyPath:@"values.usesAlternatingRowBackgroundColors"] boolValue]];
}
}
The problem is, that since [change objectForKey:NSKeyValueChangeNewKey] returns
<NULL> in the log, I can't get the changed value from the change dictionary, so
I have to read it from the sharedUserDefaultsController - which works, but
seems pretty ridiculous. (Instead of checking the check boxes state, I could
have used the same approach in the 1. solution, too, BTW.) Somehow, KVO seems
to be unable to handle the boolean encoded as NSNumber. Ideas on this anybody?
Maybe the problem is that I should be using NSData to be able to use
NSUnarchiveFromData as a value transformer - but I have no clue how to put a
boolean into an NSData object or get one out of it in a manner which is
compliant to NSUnarchiveFromData.
Any ideas on how to do better?
Thanks a lot!
_______________________________________________
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]