一、倒计时
初始化信号量
- (RACSignal *)retryButtonTitleAndEnable{
static const NSInteger n = 3;
//定时器 主线程中 1秒执行一次
RACSignal *timer = [[RACSignal interval:1
onScheduler:[RACScheduler mainThreadScheduler]]
map:^id(id value) {
return nil;
}];
//将需要显示的秒数转化为一个数组
NSMutableArray *numbers = [NSMutableArray array];
for (NSInteger i = n; i >= 0; i--) {
[numbers addObject:[NSNumber numberWithInteger:i]];
}
//两个信号关联 用zip保证每一秒取一个元素
return [[[numbers.rac_sequence.signal zipWith:timer]
map:^id(RACTuple *tuple) {
//秒数
NSNumber *number = tuple.first;
NSInteger count = number.integerValue;
//返回一个 集合对象(要显示的文字, 是否完成)
if (count == 0) {
return RACTuplePack(@"",[NSNumber numberWithBool:YES]);
}else{
NSString *title = [NSString stringWithFormat:@"重试 %lds",(long)count];
return RACTuplePack(title,[NSNumber numberWithBool:NO]);
}
}]
takeUntil:self.rac_willDeallocSignal] ;
;
}
关于zipWith
当用 zipWith 链接A和B的时候,只有在A.B每隔都至少发送过一次消息的时候才会执行zipWith的方法,它的返回值是一个集合,也就是数组,同时包含了A和B的打印结果。
调用
[[[[self.sendBtn rac_signalForControlEvents:UIControlEventTouchUpInside]
flattenMap:^id(id value) {
return [self retryButtonTitleAndEnable];
}]
takeUntil:self.rac_willDeallocSignal]
subscribeNext:^(RACTuple *tuple) {
NSString *title = tuple.first;
[self.sendBtn setTitle:title forState:(UIControlStateNormal)];
self.sendBtn.enabled = ((NSNumber *)tuple.second).boolValue;
}];
二、登录
方法准备
//验证用户名有效性
- (BOOL)isValidUserName:(NSString *)username{
return username.length > 9;
}
//验证密码有效性
- (BOOL)isValidUserPW:(NSString *)userpw{
return userpw.length > 8;
}
//模拟登录请求
- (void)signInWithName:(NSString *)name pw:(NSString *)pw complete:(void (^)(BOOL isSuccess))handle{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
handle(YES);
});
}
//初始化登录信号量
- (RACSignal *)signInSignal{
return [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
[self signInWithName:@"" pw:@"" complete:^(BOOL isSuccess) {
[subscriber sendNext:@(isSuccess)];
[subscriber sendCompleted];
}];
return nil;
}];
}
调用
- (void)initLoginPipeline{
//创建信号量
RACSignal *validUsernameSignal = [self.userNameTextField.rac_textSignal map:^id(NSString *value) {
return @([self isValidUserName:value]);
}];
RACSignal *validUserPWSignal = [self.userPWTextField.rac_textSignal map:^id(NSString *value) {
return @([self isValidUserPW:value]);
}];
//根据输入文字的有效性更改背景颜色
RAC(self.userNameTextField,backgroundColor) = [validUsernameSignal map:^id(NSNumber *value) {
return [value boolValue] ? [UIColor clearColor]: [UIColor yellowColor];
}];
RAC(self.userPWTextField,backgroundColor) = [validUserPWSignal map:^id(NSNumber *value) {
return [value boolValue] ? [UIColor clearColor]: [UIColor yellowColor];
}];
//登录
RACSignal *signUpActiveSignal = [RACSignal combineLatest:@[validUserPWSignal,validUsernameSignal]
reduce:^(NSNumber *userNameVaild,NSNumber *userPWVaild){
return @([userNameVaild boolValue] && [userPWVaild boolValue]);
}];
[signUpActiveSignal subscribeNext:^(NSNumber *signupActive) {
self.commitBtn.enabled = [signupActive boolValue];
}];
[[[self.commitBtn rac_signalForControlEvents:UIControlEventTouchUpInside]
flattenMap:^RACStream *(id value) {
return [self signInSignal];
}]
// 处理登录
subscribeNext:^(id x) {
NSLog(@"but clicked %@",x);
}];
}
三、键盘相关
- (void)initKeyBoardPipeline{
RACSignal *keyboardWillShowNotification =
[[[NSNotificationCenter defaultCenter]
rac_addObserverForName:UIKeyboardWillShowNotification object:nil
]
map:^id(NSNotification *notification) {
NSDictionary *userInfo = notification.userInfo;
NSValue *avalue = [userInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
return avalue;
}];
[[[[[[NSNotificationCenter defaultCenter]
rac_addObserverForName:UIKeyboardWillHideNotification object:nil
]
map:^id(id value) {
return [NSValue valueWithCGRect:CGRectZero];
}]merge:keyboardWillShowNotification]
takeUntil:self.rac_willDeallocSignal]
subscribeNext:^(NSValue *value) {
//处理键盘事件
NSLog(@"value %@",value);
} completed:^{
NSLog(@"completed");
}];
}