RAC - 點(diǎn)擊獲取驗(yàn)證碼 demo

文章系列
《ReactiveCocoa 概述》
《RACSignal》
《RACDisposable》
《RACSubject、RACReplaySubject(內(nèi)附冷信號(hào)和熱信號(hào)的區(qū)別)》
《集合RACTuple、RACSequence》
《RAC 中的通知、代理、KVO, 基本事件、方法的監(jiān)聽(tīng)》
《rac_liftSelector》
《RACMulticastConnection》
《RACCommand》
《RAC - 核心方法bind》
《RAC - 定時(shí)器》
《RACScheduler》
《RAC - 點(diǎn)擊獲取驗(yàn)證碼 demo》
《RAC - 映射(Map & flattenMap)》
《RAC信號(hào)操作解釋合集》
《RAC - 信號(hào)的生命周期》

思路分析:

  • 其實(shí)就是RACCommand 的使用
  • 第一個(gè)信號(hào)是一個(gè)做減一操作的計(jì)時(shí)器 -> countSignal
  • 第二個(gè)信號(hào)為phoneTextfield 的位數(shù)是否為11 位, 返回bool 值, 根據(jù)需要求可以在里面添加其他判斷.
  • 通過(guò)RACCommandinitWithEnabled初始化方法, 將這兩個(gè)信號(hào)作為參數(shù), 進(jìn)而來(lái)控制最終結(jié)果
- (void)fetchCodeTest {

    // 定義一個(gè)返回值類(lèi)型為閉包的屬性
    RACSignal *(^counterSignal)(NSNumber *count) = ^RACSignal * (NSNumber *count) {
        
        // 主線(xiàn)程 間隔一秒的定時(shí)器
        RACSignal *timerSignal = [RACSignal interval:1 onScheduler:RACScheduler.mainThreadScheduler];
        
        // scanWithStart 掃描操作, 對(duì)每次一信號(hào)值, 進(jìn)行處理
        // count 為起始值, 也就是第一次的running
        // next 為信號(hào)值, 從時(shí)間早晚排序
        // running 為上一次的閉包中return 的結(jié)果.
        RACSignal *countSignal = [[timerSignal scanWithStart:count reduce:^id _Nullable(NSNumber *running, id next) {
            
            // 這里是每一秒減一, 因?yàn)槭堑褂?jì)時(shí)操作
            NSLog(@"scanWithStart中閉包操作:%zd-%@", running.integerValue, next);
            return @(running.integerValue - 1);
            
            // takeUntilBlock: 通過(guò)閉包內(nèi)部操作 來(lái)控制外部信號(hào), 也就是說(shuō),當(dāng)閉包內(nèi)部滿(mǎn)足什么條件時(shí), 閉包外部的信號(hào)就終止訂閱
            // 返回yes的時(shí)候,停止信號(hào)的訂閱
        }] takeUntilBlock:^BOOL(NSNumber *x) {
            return x.integerValue < 0;
        }];
        
        // startWith: 信號(hào)會(huì)首先發(fā)送一個(gè)值,這個(gè)信號(hào)結(jié)束, 下一個(gè)才開(kāi)始, 一般都為初始值
        return [countSignal startWith:count];
    };
    
    // 監(jiān)聽(tīng)輸入框位數(shù)是否為11 位數(shù)的一個(gè)信號(hào), 信號(hào)的結(jié)果為bool 類(lèi)型
    RACSignal *enableSignal = [self.phoneTextfield.rac_textSignal map:^id _Nullable(NSString *value) {
        return @(value.length == 11);
    }];
    
    // 定義一個(gè)多信號(hào)管理工具
    RACCommand *command = [[RACCommand alloc] initWithEnabled:enableSignal signalBlock:^RACSignal * _Nonnull(id  _Nullable input) {
        return counterSignal(@10);
    }];
    
    // 原始信號(hào)必須是發(fā)送信號(hào)的信號(hào)(sendNext (RACSignal)…),發(fā)送的信號(hào)會(huì)被訂閱,直到發(fā)送下一個(gè)信號(hào),前一個(gè)被發(fā)送的信號(hào)就終止訂閱,方法的作用是,每次訂閱最新的信號(hào)。和map一起往往被認(rèn)為是替代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:@"點(diǎn)擊獲取驗(yàn)證碼"];
    
    [self.fetchCodeButton rac_liftSelector:@selector(setTitle:forState:) withSignals:[RACSignal merge:@[counterStringSignal, resetStringSignal]], [RACSignal return:@(UIControlStateNormal)], nil];
    
    // rac_liftSelector 就等價(jià)與下面注釋掉的內(nèi)容
//    [[RACSignal merge:@[counterStringSignal, resetStringSignal]] subscribeNext:^(id  _Nullable x) {
//        [self.fetchCodeButton setTitle:x forState:UIControlStateNormal];
//    }];
    
    self.fetchCodeButton.rac_command = command;
}

.End

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容