我发送 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。