带有ReactiveCocoa的MVVM:限制视图模型中的UITextField的文本长度

我正在采用MVVM与ReactiveCocoa。 现在我有一个UITextField,我需要限制它的最大文本长度为100。

在我看来:

- (void)bindViewModel { RAC(self.viewModel, text) = self.textField.rac_textSignal; [RACObserve(self.viewModel, text) subscribeNext:(NSString *text) { self.textField.text = text; }]; } 

在我看来的模型

 - (id)init { [RACObserve(self, text) subscribeNext:^(NSString *x) { //block 1 if (x.length > maxTextLength) { x = [x substringToIndex:maxTextLength]; } }]; } 

但是这不行, block 1从来不叫。

通过使用MVVM,我相信文本长度控制逻辑应该放在我的视图模型中,但是实现这一点的正确方法是什么?

正如在这个答案中所描述的:你可以从文本字段中获取rac_textSignal ,并使用map来将string修剪为所需的长度。 然后使用RACmacros将映射的信号绑定到文本字段。 正如你所说,视图模型不应该有一个参考视图。 但它可以传递一个信号并返回一个映射的信号。

在一个视图中:

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

这也使得文本控制逻辑易于testing – 在unit testing中,您可以传递类似于-[RACSignal return:@"foo"]到视图模型,并检查输出是否正确。