RAC 学习笔记(一)

一、倒计时
初始化信号量

- (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 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");
     }];
}

你可能感兴趣的:(RAC 学习笔记(一))