上一篇RAC,已经把信号的基本几步介绍完了(创建->订阅->发送->处理),这里,我们再详细说一下信号的处理,也就是第四步。
这里我们以登录页面为例,一步步来实现一系列需求:
需求:
- 用户名格式输入正确之前,当前的TextField是红的,格式正确之后变正常;
- 密码长度输入到6个之前,当前的TextField是红的,长度够6个,变正常;
- 满足前两者之前 “登录”按钮是无效的。
Map
-
作用:
映射。把源信号映射成新的值。 - 使用:
// 用户名
RACSignal *nameSignal = [self.tf_userName.rac_textSignal
map:^id(NSString *text) {
return @([self isMobileNumber:text]);
}];
[nameSignal subscribeNext:^(id x) {
self.tf_userName.backgroundColor = [x boolValue] ? [UIColor clearColor] : RGBACOLOR(255.0, 0, 0, 0.2);
}];
// 密码
RACSignal *passWordSignal = [self.tf_passWord.rac_textSignal
map:^id(NSString *text) {
return @([self isPassword:text]);
}];
[passWordSignal subscribeNext:^(id x) {
self.tf_passWord.backgroundColor = [x boolValue] ? [UIColor clearColor] : RGBACOLOR(255.0, 0, 0, 0.2);
}];
-
分析:
当textField中内容发生变化时,首先会对信号进行一次转换,这里面的isMobileNumber
和isPassword
是一个手机号的正则方法和密码的正则方法,返回的是BOOL类型变量。这里我们将输入的内容用Map方法,转化成一个BOOL类型的值发送出去。接收的时候,我们对接收的值(这时候接到的已经是BOOL类型的值了)进行判断,如果为真,将红色提示框变为透明,否则反之。
flattenMap
-
作用:
把源信号映射成一个新的信号,它可以是任何类型。 - 使用:
RACSignal *nameSignal = [self.tf_userName.rac_textSignal
flattenMap:^RACSignal*(NSString *text) {
return [RACSignal return:[NSString stringWithFormat:@"改变后的信号:%@", text]];
}];
[nameSignal subscribeNext:^(id x) {
NSLog(@"%@", x);
}];
-
分析:
flattenMap在这里将源信号转化为一个新的信号,它与map的不同,主要在于flattenMap返回的是一个信号,而map返回的是一个值。
聚合信号
在单独的textField中,我们只需要根据输入的字符来判断textField的样式就可以了,但是如果需要完成我们的任务三“满足前两者之前 “登录”按钮是无效的。”我们需要把两个信号聚合到一起来判断。
- 使用
RACSignal *loginSignal = [RACSignal combineLatest:@[nameSignal, passWordSignal] reduce:^id(NSNumber *userName, NSNumber *userPassWord){
return @([userName boolValue] && [userPassWord boolValue]);
}];
[loginSignal subscribeNext:^(id x) {
self.bt_Login.enabled = [x boolValue];
NSLog(@"%@", x);
}];
-
分析
我们用combineLatest:reduce将两个信号聚合到一起,产生一个新的信号,当信号中国其中任何信号有新值时,都会执行reduce的block里面的方法。block再将信号发送个下一个订阅者。
filter
作用:
过滤信号。过滤掉不满足条件的信号,获取想要得到的信号。使用:
[[self.tf_userName.rac_textSignal filter:^BOOL(NSString *value) {
NSLog(@"原信号: %@", value);
return [self isMobileNumber:value];
}] subscribeNext:^(id x) {
NSLog(@"是真是手机号的信号:%@", x);
}];
-
分析:
开发中,我们经常会用到判断手机号,甚至判断银行卡所属银行之类的功能。这些数据,有些事需要收费的,要实现格式正确,立马显示结果,我们不得不实时调用接口来判断,通过这个方法,我们用正则表达式可以做到初步的筛选,节省开销与流量。
本文也是写的比较着急,还有很多知识点没有列举出来,接下来我会再来完善,如有错误之处,大家指点出来,谢谢。