reactivecocoa true shouldChangeCharactersInRange textfield等效

时间:2014-05-28 07:42:08

标签: ios objective-c uitextfield reactive-cocoa

我从reactiveCocoa开始,我在UITextfield上遇到了一些麻烦。 我尝试对textField进行基本检查,只显示4位数。

我尝试遵循这个例子: http://nshipster.com/reactivecocoa/ 但在这里,shouldChangeCharactersInRange始终为true,因此文本字段始终更新。

我尝试了2个解决方案:

[RACSignal combineLatest:@[self.pinDigitField.rac_textSignal]
 reduce:^(NSString *pinDigit) {
       NSCharacterSet *numbersOnly =[NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
       NSCharacterSet *characterSetFromTextField = [NSCharacterSet characterSetWithCharactersInString:pinDigit];

return @([numbersOnly isSupersetOfSet:characterSetFromTextField] && text.length < 5);
                                                  }];

和这一个

[[self.pinDigitField.rac_textSignal
  filter:^BOOL(id value) {
      NSString *text = value; 
      NSCharacterSet *numbersOnly = [NSCharacterSet characterSetWithCharactersInString:@"0123456789"];
      NSCharacterSet *characterSetFromTextField = [NSCharacterSet characterSetWithCharactersInString:text];

      BOOL stringIsValid = [numbersOnly isSupersetOfSet:characterSetFromTextField] && text.length < 5 ;return stringIsValid;
  }]subscribeNext:^(id x) {
      NSLog(@"valid");
  }];

在这两种情况下,我都不能在UITextfield中编写新的字符。

有人有想法吗?

1 个答案:

答案 0 :(得分:8)

  

我尝试对textField进行基本检查,只显示4位数

让我们首先将文本信号分配给文本字段的text属性:

RAC(self.textField, text) = self.textField.rac_textSignal;

现在每次文本字段更改时,textField.text都会设置为文本字段的内容。像这样毫无意义,但现在我们可以将值映射到只允许数字:

RAC(self.textField, text) = [self.textField.rac_textSignal map:^id(NSString *value) {
    return [value stringByTrimmingCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]];
}];

要将文本字段限制为仅4个字符,则无法使用过滤器。过滤器会阻止信号触发,但是因为您在文本字段中输入,您仍然会对其进行更改。相反,让我们使用另一个地图将所有值修剪为4的长度:

RAC(self.textField, text) = [[self.textField.rac_textSignal map:^id(NSString *value) {
    return [value stringByTrimmingCharactersInSet:[[NSCharacterSet decimalDigitCharacterSet] invertedSet]];
}] map:^id(NSString *value) {
    if (value.length > 4) {
        return [value substringToIndex:4];
    } else {
        return value;
    }
}];