ReactiveCocoa: ограничить длину ввода UITextfield, но разрешить неограниченную длину при выборе символов

При вводе текста на китайском языке вы вводите английские символы, а затем выбираете китайские символы, прежде чем выбирать китайские символы, английские символы находятся в выбранном состоянии (-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 range и text текстового поля?


person CarmeloS    schedule 06.07.2015    source источник


Ответы (1)


Я считаю логику ввода китайских иероглифов помощником для пользовательского ввода, поэтому модель представления не должна знать об этом.

Основываясь на ответе на ваш предыдущий вопрос, вы можете сделать что-то вроде этого:

В категорию 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];
    }];
}
person Jakub Vano    schedule 07.07.2015