views:

98

answers:

1

Here's my setup:

  • myTextField is bound to a key in the Shared User Defaults Controller. The user can only enter numbers in the text field.
  • Each time my application loads, I load default preferences (from the app's Resources folder) using [[NSUserDefaults standardUserDefaults] registerDefaults: ... ].
  • myMenuItem's title is bound to the same key in the Shared User Defaults Controller.

The issue:

When myTextField is empty, myMenuItem receives the default value that was loaded using registerDefaults: instead of some value that represents the empty field (I would expect 0 or nil).

For example, when the NSTextField is empty the menu item receives "2", the value that was loaded using registerDefaults:, instead of some value that means that the field is empty.

If I comment the registerDefaults: code, the binding returns nil as I would expect when there is nothing in the NSTextField.

I tried to mess around with many of the bindings' settings as well as experiment with placeholder values and I looked at the Cocoa Bindings and User Defaults docs but I could not find the solution.

Expected behavior:

  • When the text field is empty, I want myMenuItem to reflect that instead of using the default value that was registered using registerDefaults:.

Any help would be greatly appreciated.

A: 

I got some hints from the nice folks at irc.freenode.org #macdev and found the following to be the solution to my problem:

Creating a subclass of NSFormatter (or NSNumberFormatter in my case) and overriding getObjectValue:forString:errorDescription: as follows overrides the default behaviour of returning nil (which makes the binding use the registered default value) to instead return 0 when the text field is empty.

- (BOOL)getObjectValue:(id *)anObject forString:(NSString *)string errorDescription:(NSString **)error {
    if ([string isEqualToString:@""]) {
        *anObject = [NSNumber numberWithInt:0];
        return YES;
    } else {
        return [super getObjectValue:anObject forString:string errorDescription:error];
    }
}

A NSValueTransformer subclass' reverse conversion method would have also worked for this.

Form