reactivecocoa true shouldChangeCharactersInRange t

2020-07-29 23:56发布

i begin with reactiveCocoa and i have some trouble with UITextfield. i try to do a basic check on a textField to display only 4 digit.

i try to follow this exemple: http://nshipster.com/reactivecocoa/ but in here, shouldChangeCharactersInRange is always true so the textfield is always updated.

i tried 2 solution :

[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);
                                                  }];

and this one

[[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");
  }];

in both case i can't simply not write the new caracter in the UITextfield.

does anybody have an idea?

1条回答
唯我独甜
2楼-- · 2020-07-30 00:30

i try to do a basic check on a textField to display only 4 digit

Let's start by assigning the text signal to the text property of the text field:

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

Now every time the text field changes, textField.text is set to the content of the text field. Pretty pointless like this, but now we can map the values to only allow numbers:

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

To limit the text field to only 4 characters you can't use a filter. A filter would prevent the signal from firing, but because you are typing in the text field you would still get changes in it. Instead let's use another map to trim all values to a length of 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;
    }
}];
查看更多
登录 后发表回答