一般来说,使用ReactiveObjC
最好和viewmodel
一起使用。
单向绑定
RAC(self.textField, text) = RACObserve(self.viewModel, value);
viewModel.value
改变时,动态改变textField.text
一般情况下,textField
会放在ViewController
中
双向绑定
RAC(self.textField, text) = RACObserve(self.viewModel, value);
@weakify(self);
[self.textField.rac_textSignal subscribeNext:^(NSString * _Nullable x) {
@strongify(self);
self.viewModel.value = x;
}];
单向绑定的基础上,在textField
监听信号里面,动态改变viewModel.value
。
注:self.textField.rac_textSignal subscribeNext:
能监听到每次输入的变化
还有一种双向绑定
RACChannelTo
也可以做到相互绑定,与上面不同的一点,不能监听到每次输入的变化。
RACChannelTo(self.textField, text) = RACChannelTo(self.viewModel, value);
信号几种处理函数
-
filter
筛选
- (RACSignal *)forbiddenNameSignal{
@weakify(self);
// 筛选出`[self.forbiddenNames containsObject:newName]`信号,后面会监听这个信号,做一个提醒框
return [RACObserve(self, name) filter:^BOOL(NSString *newName) {
@strongify(self);
return [self.forbiddenNames containsObject:newName];
}];
}
-
map
遍历
RAC(self.scoreStepper,hidden) = [RACObserve(self, scoreUpdates) map:^id _Nullable(NSNumber *value) {
return @(value.integerValue >= self.viewModel.maxScoreUpdates);
}];
监听scoreUpdates
每次变化的值,并与maxScoreUpdates
比较。
-
skip
可以理解为略过多少次信号
[[[self.updateBtn rac_signalForControlEvents:UIControlEventTouchUpInside] skip:kMaxUploader - 1] subscribeNext:^(__kindof UIControl * _Nullable x) {
self.nameTextField.enabled = NO;
self.scoreStepper.hidden = self.updateBtn.hidden = YES;
}];
下面表示,按钮点击kMaxUploader - 1
次后,就执行
-
take
可以理解为获取多少次信号
[[[RACObserve(self.scoreStepper, value) skip:1] take:self.viewModel.maxScoreUpdates]
subscribeNext:^(id _Nullable x) {
@strongify(self);
self.scoreUpdates++;
}];
也可以和skip
结合一起使用,有效次数的区间(skip, skip+take]
下面表示,忽略第一个信号,然后获取maxScoreUpdates
次信号
-
combineLatest
可以结合多个信号,一般搭配reduce
使用,是有顺序的。
merge
也可以结合多个信号,但没有严格的顺序。
- (RACSignal *)modelIsValidSignal{
@weakify(self);
return [RACSignal combineLatest:@[RACObserve(self, name), RACObserve(self, score)] reduce:^id _Nonnull(NSString *newName, NSNumber *newScore){
@strongify(self);
return @(newName.length > 0 &&
![self.forbiddenNames containsObject:newName] &&
newScore.integerValue >= self.minScore);
}];
}
下面表示,结合了name、score
信号,同时reduce
过滤了其中的信号
注:reduce
不知道结合的信号有哪些,需要手动添加block的参数值,参数值一定要按照结合的顺序写,例如下面的^id _Nonnull(NSString *newName, NSNumber *newScore)
网友评论