以下是我的设置:
myTextField
绑定到共享用户默认控制器中的密钥。用户只能在文本字段中输入数字。[[NSUserDefaults standardUserDefaults] registerDefaults: ... ]
加载默认首选项(来自应用程序的Resources文件夹)。myMenuItem
的标题绑定到共享用户默认值控制器中的相同密钥。问题:
当myTextField
为空时,myMenuItem
会收到使用registerDefaults:
加载的默认值,而不是代表空字段的某个值(我希望0或nil
)。
例如,当NSTextField
为空时,菜单项会收到“2”,即使用registerDefaults:
加载的值,而不是某个值,表示该字段为空。
如果我对registerDefaults:
代码发表评论,那么当nil
中没有任何内容时,绑定会返回NSTextField
。
我试图搞砸了许多绑定的设置以及实验占位符值,我查看了Cocoa Bindings和User Defaults文档,但我找不到解决方案。
预期行为:
myMenuItem
反映该内容,而不是使用使用registerDefaults:
注册的默认值。非常感谢任何帮助。
答案 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选择以他们的方式做到这一点超出了我的范围。