我正在尝试使用NSTextField进行整数用户输入.文本字段绑定到NSNumber属性,在setter方法中我清理输入值(确保它是一个int)并在必要时设置属性.我发送了willChangeValueForKey:和didChangeValueForKey:,但是当该文本字段仍处于活动状态时,UI不会更新为新值.
例如,我可以在文本字段中键入"12abc",setter方法清除为"12",但文本字段仍显示"12abc".
我在界面构建器中选中了"连续更新值".
(我也注意到setter方法接收的是NSString,而不是NSNumber.这是正常的吗?)
将NSTextField连接到NSNumber的正确方法是什么?该属性的setter方法是什么样的?如何防止非数字值出现在文本字段中?
我发送了willChangeValueForKey:和didChangeValueForKey:,但是当该文本字段仍处于活动状态时,UI不会更新为新值.
发送这些消息的理由很少.通常,通过实现和使用访问器(或者更好的属性),您可以更好,更干净地完成相同的工作.当你这样做时,KVO会为你发送通知.
在您的情况下,您想要拒绝或过滤虚假输入(如"12abc").此任务的正确工具是键值验证.
要启用此功能,请检查IB中绑定的"立即验证"框,并实现验证方法.
过滤:
- (BOOL) validateMyValue:(inout NSString **)newValue error:(out NSError **)outError { NSString *salvagedNumericPart; //Determine whether you can salvage a numeric part from the string; in your example, that would be “12”, chopping off the “abc”. *newValue = salvagedNumericPart; //@"12" return (salvagedNumericPart != nil); }
拒绝:
- (BOOL) validateMyValue:(inout NSString **)newValue error:(out NSError **)outError { BOOL isEntirelyNumeric; //Determine whether the whole string (perhaps after stripping whitespace) is a number. If not, reject it outright. if (isEntirelyNumeric) { //The input was @"12", or it was @" 12 " or something and you stripped the whitespace from it, so *newValue is @"12". return YES; } else { if (outError) { *outError = [NSError errorWithDomain:NSCocoaErrorDomain code: NSKeyValueValidationError userInfo:nil]; } //Note: No need to set *newValue here. return NO; } }
(我也注意到setter方法接收的是NSString,而不是NSNumber.这是正常的吗?)
是的,除非您使用将字符串转换为数字的值转换器,将数字格式器连接到formatter
插座,或者在验证方法中将NSNumber替换为NSString.