问题
I'm adopting MVVM with ReactiveCocoa. Now I have a UITextField which I need to limit it's max text length to 100.
In my view:
- (void)bindViewModel
{
RAC(self.viewModel, text) = self.textField.rac_textSignal;
[RACObserve(self.viewModel, text) subscribeNext:(NSString *text) {
self.textField.text = text;
}];
}
In my view model
- (id)init
{
[RACObserve(self, text) subscribeNext:^(NSString *x) {
//block 1
if (x.length > maxTextLength) {
x = [x substringToIndex:maxTextLength];
}
}];
}
But this doesn't work, block 1
is never called.
By using MVVM, I believe that the text length control logic should be put in my view model, but what is the proper way to achieve this?
回答1:
As described in this answer: you can take rac_textSignal
from the text field and use map
to trim the string to the desired length. Then bind the mapped signal to the text field using RAC
macro.
As you noted, view model shouldn't have a reference to the view. But it can be passed a signal and return a mapped signal.
In a view:
RAC(self.textField, text) = [self.viewModel validatedTextWithSignal:self.deviceName.rac_textSignal];
in your view model:
- (RACSignal *)validatedTextWithSignal:(RACSignal *)signal {
NSUInteger kMaxLength = 5;
return [signal map:^id(NSString *text) {
return text.length <= kMaxLength ? text : [text substringToIndex:kMaxLength];
}];
}
This also makes the text control logic easy to test - in unit tests, you can pass something like -[RACSignal return:@"foo"]
to the view model and check if the output is correct.
来源:https://stackoverflow.com/questions/31228116/mvvm-with-reactivecocoa-limit-the-text-length-of-a-uitextfield-in-view-model