想了很久,不知道RAC+MVVM如何完美的嵌入到代码中,最终还是决定先从RAC入手吧。尝试着MVC和RAC能不能碰撞出火花。下面两个demo只是一个简短的开始,还在努力研究中..
话不多说,直接上代码吧
先看下效果图
一个简单的登录按钮和输入框的输入监听绑定,有兴趣的道友也可以自己发散改良,我只是简单的写了一下如何监听的。
RACSignal *userSignal = self.userTextField.rac_textSignal; // 对用户名输入框的输入得到一个信号量
RACSignal *pasSignal = self.psdTextField.rac_textSignal; // 密码输入框的输入同样得到一个信号量
RACSignal *enabled = [[RACSignal combineLatest:@[userSignal, pasSignal]] map:^id _Nullable(RACTuple * _Nullable value) {
return @([value.first length] > 0 && [value.second length] >5);
}];// 将两个输入框的信号量进行捆绑然后进行转换返回一个BOOL型的信号量
// enabled信号量就是控制按钮的点击状态,在实际开发中Block里面可以做自己想要的操作,例如请求验证码什么的
self.loginBtn.rac_command = [[RACCommand alloc] initWithEnabled:enabled signalBlock:^RACSignal * _Nonnull(id _Nullable input) { return [RACSignal createSignal:^RACDisposable * _Nullable(id_Nonnull subscriber) {
[subscriber sendNext:@"登录中..."];
// 模拟网路延时
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[subscriber sendNext:@"登录"];
[subscriber sendCompleted];
});
return [RACDisposable disposableWithBlock:^{
}];
}];
}];
// @weakify(self) 和 @strongify(self)是成对出现的,是RAC对self的强弱引用
// executionSignals 官方介绍,我英语不好,大家自行翻译哈
/// A signal of the signals returned by successful invocations of -execute:
/// (i.e., while the receiver is `enabled`).
///
/// Errors will be automatically caught upon the inner signals, and sent upon
/// `errors` instead. If you _want_ to receive inner errors, use -execute: or
/// -[RACSignal materialize].
///
/// Only executions that begin _after_ subscription will be sent upon this
/// signal. All inner signals will arrive upon the main thread.
// 让后我们订阅这个信号量,得到的就是我们在上面Block中发送的东西
@weakify(self)
[[self.loginBtn.rac_command executionSignals] subscribeNext:^(RACSignal* _Nullable x) {
@strongify(self)
[x subscribeNext:^(id _Nullable x) {
NSLog(@"%@", x);
[self.loginBtn setTitle:x forState:UIControlStateNormal];
}];
}];
--------------这是分割线---------
下面这个demo是通过对silder和textField的监听,然后改变backView的背景颜色
直接上代码吧
// 初始化值
self.redTextField.text = self.greenTextField.text = self.blueTextField.text = @"0.5";
// 进行绑定
RACSignal *redSignal = [self blinderSlider:self.redSlider textField:self.redTextField];
RACSignal *greenSignal = [self blinderSlider:self.greenSlider textField:self.greenTextField];
RACSignal *blueSignal = [self blinderSlider:self.blueSlider textField:self.blueTextField];
// 将绑定的信号合并成一个信号并map转换成一个颜色信号量返回
RACSignal *changeSignal = [[RACSignal combineLatest:@[redSignal, greenSignal, blueSignal]] map:^id _Nullable(RACTuple * _Nullable value) {
return [UIColor colorWithRed:[value[0] floatValue] green:[value[1] floatValue] blue:[value[2] floatValue] alpha:1.0];
}];
// 将得到的颜色信号量通过RAC监听赋值给colorView的backgroundColor
RAC(self.colorView, backgroundColor) = changeSignal;
// 将slider和textField的改变转换成信号并进行相互绑定,然后将他们merge成一个信号返回
- (RACSignal *)blinderSlider:(UISlider *)slider textField:(UITextField *)textField {
RACSignal *inputSignal = [textField rac_textSignal];
RACChannelTerminal *silderSignal = [slider rac_newValueChannelWithNilValue:nil];
RACChannelTerminal *textSignal = [textField rac_newTextChannel];
[[silderSignal map:^id _Nullable(id _Nullable value) {
return [NSString stringWithFormat:@"%.2f", [value floatValue]];
}] subscribe:textSignal];
[textSignal subscribe:silderSignal];
return [[textSignal merge:silderSignal] merge:inputSignal];
}
好了,本次的小demo就到这里了,有什么问题欢迎留言提问,谢谢各位道友。
最后附上源码地址:https://github.com/LMfiles/RAC_LoginView.git
https://github.com/LMfiles/RAC_ChangeColor.git 欢迎star