RAC - 点击获取验证码 demo
2020-10-20 本文已影响0人
下班不写程序
文章系列
《ReactiveCocoa 概述》
《RACSignal》
《RACDisposable》
《RACSubject、RACReplaySubject(内附冷信号和热信号的区别)》
《集合RACTuple、RACSequence》
《RAC 中的通知、代理、KVO, 基本事件、方法的监听》
《rac_liftSelector》
《RACMulticastConnection》
《RACCommand》
《RAC - 核心方法bind》
《RAC - 定时器》
《RACScheduler》
《RAC - 点击获取验证码 demo》
《RAC - 映射(Map & flattenMap)》
《RAC信号操作解释合集》
《RAC - 信号的生命周期》
思路分析:
- 其实就是
RACCommand
的使用- 第一个信号是一个做减一操作的计时器 ->
countSignal
- 第二个信号为
phoneTextfield
的位数是否为11 位, 返回bool
值, 根据需要求可以在里面添加其他判断.- 通过
RACCommand
的initWithEnabled
初始化方法, 将这两个信号作为参数, 进而来控制最终结果
- (void)fetchCodeTest {
// 定义一个返回值类型为闭包的属性
RACSignal *(^counterSignal)(NSNumber *count) = ^RACSignal * (NSNumber *count) {
// 主线程 间隔一秒的定时器
RACSignal *timerSignal = [RACSignal interval:1 onScheduler:RACScheduler.mainThreadScheduler];
// scanWithStart 扫描操作, 对每次一信号值, 进行处理
// count 为起始值, 也就是第一次的running
// next 为信号值, 从时间早晚排序
// running 为上一次的闭包中return 的结果.
RACSignal *countSignal = [[timerSignal scanWithStart:count reduce:^id _Nullable(NSNumber *running, id next) {
// 这里是每一秒减一, 因为是倒计时操作
NSLog(@"scanWithStart中闭包操作:%zd-%@", running.integerValue, next);
return @(running.integerValue - 1);
// takeUntilBlock: 通过闭包内部操作 来控制外部信号, 也就是说,当闭包内部满足什么条件时, 闭包外部的信号就终止订阅
// 返回yes的时候,停止信号的订阅
}] takeUntilBlock:^BOOL(NSNumber *x) {
return x.integerValue < 0;
}];
// startWith: 信号会首先发送一个值,这个信号结束, 下一个才开始, 一般都为初始值
return [countSignal startWith:count];
};
// 监听输入框位数是否为11 位数的一个信号, 信号的结果为bool 类型
RACSignal *enableSignal = [self.phoneTextfield.rac_textSignal map:^id _Nullable(NSString *value) {
return @(value.length == 11);
}];
// 定义一个多信号管理工具
RACCommand *command = [[RACCommand alloc] initWithEnabled:enableSignal signalBlock:^RACSignal * _Nonnull(id _Nullable input) {
return counterSignal(@10);
}];
// 原始信号必须是发送信号的信号(sendNext (RACSignal)…),发送的信号会被订阅,直到发送下一个信号,前一个被发送的信号就终止订阅,方法的作用是,每次订阅最新的信号。和map一起往往被认为是替代flattenMap的方案。
RACSignal *counterStringSignal = [[command.executionSignals switchToLatest] map:^id _Nullable(NSNumber *value) {
return [value stringValue];
}];
RACSignal *resetStringSignal = [[command.executing filter:^BOOL(NSNumber * _Nullable value) {
return !value.boolValue;
}] mapReplace:@"点击获取验证码"];
[self.fetchCodeButton rac_liftSelector:@selector(setTitle:forState:) withSignals:[RACSignal merge:@[counterStringSignal, resetStringSignal]], [RACSignal return:@(UIControlStateNormal)], nil];
// rac_liftSelector 就等价与下面注释掉的内容
// [[RACSignal merge:@[counterStringSignal, resetStringSignal]] subscribeNext:^(id _Nullable x) {
// [self.fetchCodeButton setTitle:x forState:UIControlStateNormal];
// }];
self.fetchCodeButton.rac_command = command;
}
.End