ReactiveCocoa:限制UITextfield的输入长度,但在选择字符时允许无限长度

时间:2015-07-06 03:13:10

标签: ios mvvm reactive-cocoa

输入中文文本时,输入英文字符然后选择中文字符,在选择汉字之前,英文字符处于选中状态(-markedRange)。 在使用ReactiveCocoa之前,我可以这样做:

UITextField's UIControlEventEditingChanged事件回调中:

    const NSUInteger limitLength = 10;
    NSString *tobeString = textField.text;
    UITextRange *selectedRange = [textField markedTextRange];
    BOOL nothingSelected = (selectedRange==nil || selectedRange.isEmpty);
    if (nothingSelected) {
        if (tobeString.length > addressItemNameLimitLength) {
            textField.text = [tobeString substringToIndex:limitLength];
        }
    }
    self.textField.text = textField.text;

但在MVVM with ReactiveCocoa中,我无法在UITextField中获得对view model的引用,如何获得marked rangetext的{​​{1}}文本字段同时?

1 个答案:

答案 0 :(得分:0)

我认为输入中文字符的逻辑是用户输入的帮助,因此视图模型不应该知道这一点。

根据对your previous question的回答,你可以这样做:

UITextField类别中添加类似于-rac_textSignal的信号,但如果在编辑期间存在非空的选定范围则不会触发:

- (RACSignal *)textSignalForChineseInput {
    RACSignal* editingEventsSignal = [[[self rac_signalForControlEvents:UIControlEventEditingChanged]
                                      filter:^BOOL(UITextField* x) {
                                          return x.selectedTextRange == nil || x.selectedTextRange.isEmpty;
                                      }]
                                      merge:[self rac_signalForControlEvents:(UIControlEventAllEditingEvents & ~UIControlEventEditingChanged)]];

    @weakify(self)
    return [[[[[RACSignal
        defer:^RACSignal *{
            @strongify(self)
            return [RACSignal return:self];
        }]
        concat:editingEventsSignal]
        map:^id(UITextField* x) {
            return x.text;
        }]
        takeUntil:self.rac_willDeallocSignal]
        setNameWithFormat:@"%@ -rac_textSignalForChineseInput", self.rac_description];
}

在视图中:

RAC(self.textField, text) = [self.viewModel validatedTextWithSignal:self.deviceName.rac_textSignal];

在视图模型中:

- (RACSignal *)validatedTextWithSignal:(RACSignal *)signal {
    NSUInteger kMaxLength = 5;
    return [signal map:^id(NSString *text) {
        return text.length <= kMaxLength ? text : [text substringToIndex:kMaxLength];
    }];
}