绑定返回默认值(使用registerDefaults :)设置而不是零

时间:2010-09-29 17:00:34

标签: objective-c cocoa binding cocoa-bindings null

以下是我的设置:

  • myTextField绑定到共享用户默认控制器中的密钥。用户只能在文本字段中输入数字。
  • 每次我的应用程序加载时,我都会使用[[NSUserDefaults standardUserDefaults] registerDefaults: ... ]加载默认首选项(来自应用程序的Resources文件夹)。
  • myMenuItem的标题绑定到共享用户默认值控制器中的相同密钥。

问题:

myTextField为空时,myMenuItem会收到使用registerDefaults:加载的默认值,而不是代表空字段的某个值(我希望0或nil )。

例如,当NSTextField为空时,菜单项会收到“2”,即使用registerDefaults:加载的值,而不是某个值,表示该字段为空。

如果我对registerDefaults:代码发表评论,那么当nil中没有任何内容时,绑定会返回NSTextField

我试图搞砸了许多绑定的设置以及实验占位符值,我查看了Cocoa Bindings和User Defaults文档,但我找不到解决方案。

预期行为:

  • 当文本字段为空时,我希望myMenuItem反映该内容,而不是使用使用registerDefaults:注册的默认值。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

我从irc.freenode.org #macdev的好朋友那里得到了一些提示,发现以下内容是我问题的解决方案:

创建NSFormatter的子类(或者我的情况下为NSNumberFormatter)并覆盖getObjectValue:forString:errorDescription:,如下所示会覆盖返回nil(使绑定使用已注册的默认值)的默认行为,而是返回0当文本字段为空时。

- (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];
    }
}

NSValueTransformer子类'逆向转换方法也适用于此。

答案 1 :(得分:1)

注意:

上述解决方案不适用于字符串。也就是说,如果您的userDefault值是一个字符串,并且您已将其绑定到NSTextField的值,并且您将NSFormatter子类化并执行此操作:

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

您会发现当NSTextField为空时,绑定将设置为您最初使用-registerDefaults注册的值:而不是空字符串或nil值。我试图使用* anObject = [NSNull null];同样,但这也不起作用---绑定仍然设置为原始的默认值。

我最终设置了* anObject = @“”; (上面代码中的一个带有单个空格的字符串),这样当textField为空时,userDefaults pList中的值将设置为字符串:@“”。然后我检查每个使用该userDefault值的字符串并适当地响应(忽略单个空格并将其视为userDefault值为空)。

这是一个丑陋的黑客攻击,但我目前唯一能找到解决这个问题的方法。我在这里张贴以防万一其他人偶然发现这个帖子。如果你问我,当textField为空时,将NSTextField绑定到userDefault应该很好地将userDefault设置为空字符串!为什么Apple选择以他们的方式做到这一点超出了我的范围。