美文网首页
RAC一些常见用法(五)

RAC一些常见用法(五)

作者: dandelionYD | 来源:发表于2018-12-28 19:34 被阅读0次

    本demo详见github

    1.常见的用法

    myRedView.h
    #import <UIKit/UIKit.h>
    @interface myRedView : UIView
    @end
    
    myRedView.m
    #import "myRedView.h"
    @implementation myRedView
    -(instancetype)initWithFrame:(CGRect)frame{
        if([super initWithFrame:frame]){
            self.backgroundColor = [UIColor redColor];
            UIButton *btn  =  [UIButton new];
            btn.frame = CGRectMake(0, 0, 40, 40);
            [btn setBackgroundColor:[UIColor greenColor]];
            [self addSubview:btn];
            [btn addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
        }
        return self;
    }
    
    -(void)btnClick{
        NSLog(@"点击了红色view中的按钮");
        // 通知控制器做事情
    }
    @end
    
    RACCommonUsages.h
    #import <UIKit/UIKit.h>
    @interface RACCommonUsages : UIViewController
    @end
    
    
    RACCommonUsages.m
    
    #import "RACCommonUsages.h"
    #import "myRedView.h"
    #import <ReactiveObjC.h>
    
    @interface RACCommonUsages ()
    @property (nonatomic,assign)int  age;
    @end
    
    @implementation RACCommonUsages
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.age = 0;
        
        [self RAC_Delegate];
        
        [self RAC_KVO];
        
        [self RAC_ObserveAction];
        
        [self RAC_ObserveTextFieldAndNotification];
        
        [self ARC_MoreSituations]; 
    }
    
    //控制器要监听红色的view上的button的点击
    -(void)RAC_Delegate{
        // 1.RAC替换代理
        // RAC:判断下一个方法有没有调用,如果调用了就会自动发送一个信号给你
        // 只要self调用viewDidLoad就会转换成一个信号
        // 监听_redView有没有调用btnClick,如果调用了就会转换成信号
        myRedView *v = [[myRedView alloc]initWithFrame:CGRectMake(0, 100, 100, 200)];
        [self.view addSubview:v];
        [[v rac_signalForSelector:@selector(btnClick)] subscribeNext:^(RACTuple * _Nullable x) {
            NSLog(@"控制器知道,点击了红色的view");
        }];
    }
    
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        self.age++;
        NSLog(@"点击增的值:%d",self.age);
    }
    
    -(void)RAC_KVO{
        // 2.KVO
        // 监听哪个对象的属性改变
        // 方法调用者:就是被监听的对象
        // KeyPath:监听的属性
        // 把监听到内容转换成信号
        [[self rac_valuesForKeyPath:@"age" observer:self] subscribeNext:^(id  _Nullable x) {
            NSLog(@"监听的值%@",x);
        }];
    }
    
    -(void)RAC_ObserveAction{
        UIButton *btn  =  [UIButton new];
        btn.frame = CGRectMake(20, 400, 40, 40);
        [btn setBackgroundColor:[UIColor lightGrayColor]];
        [self.view addSubview:btn];
        //3.监听事件
        //只要产生UIControlEventTouchUpInside就会转换成信号
        [[btn rac_signalForControlEvents:UIControlEventTouchUpInside] subscribeNext:^(__kindof UIControl * _Nullable x) {
            NSLog(@"点击了btn");
        }];
    }
    
    
    -(void)RAC_ObserveTextFieldAndNotification{
        UITextField *textF = [[UITextField alloc]init];
        textF.borderStyle =  UITextBorderStyleRoundedRect;
        textF.frame = CGRectMake(200, 100, 100, 40);
        [self.view addSubview:textF];
        
        //4.监听通知
        // 只要发出这个通知,又会转换成一个信号
        [[[NSNotificationCenter defaultCenter] rac_addObserverForName:UIKeyboardWillShowNotification object:nil] subscribeNext:^(id x) {
            NSLog(@"弹出键盘");
        }];
        
        //5.监听文本框文字改变
        // 获取文本框文字改变的信号
        [textF.rac_textSignal subscribeNext:^(id x) {
            NSLog(@"%@",x);
        }];
    }
    
    //6.两种(多种)情况都有数据的时候才去做相应的事情
    -(void)ARC_MoreSituations{
        // 创建热门商品的信号
        RACSignal *signalA = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            // 处理信号
            NSLog(@"请求热门商品");
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                // 发送数据
                [subscriber sendNext:@"热门商品"];
            });
            return nil;
        }];
        
        // 创建热门商品的信号
        RACSignal *signalB = [RACSignal createSignal:^RACDisposable *(id<RACSubscriber> subscriber) {
            // 处理信号
            NSLog(@"请求最新商品");
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                // 发送数据
                [subscriber sendNext:@"最新商品"];
            });
            return nil;
        }];
        
        // RAC:就可以判断两个信号有没有都发出内容
        // SignalsFromArray:监听哪些信号的发出
        // 当signals数组中的所有信号都发送sendNext就会触发方法调用者(self)的selector
        // 注意:selector方法的参数不能乱写,有几个信号就对应几个参数
        // 不需要主动订阅signalA,signalB,方法内部会自动订阅
        [self rac_liftSelector:@selector(updateUIWithHot:new:) withSignalsFromArray:@[signalA,signalB]];
    }
    
    // 更新UI
    - (void)updateUIWithHot:(NSString *)hot new:(NSString *)new
    {
        NSLog(@"更新UI");
    }
    
    -(void)dealloc{
        NSLog(@"%s",__FUNCTION__);
    }
    @end
    

    2.RAC常见的宏

    #import "RACCommonDefines.h"
    #import <ReactiveObjC.h>
    
    @interface RACCommonDefines ()
    @property (nonatomic,strong)UITextField  *textF;
    @property (nonatomic,strong)UILabel  *showLab;
    @end
    
    @implementation RACCommonDefines
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.textF = [[UITextField  alloc]initWithFrame:CGRectMake(20, 100, 300, 40)];
        self.textF.borderStyle = UITextBorderStyleRoundedRect;
        [self.view addSubview:self.textF];
        
        self.showLab = [[UILabel alloc]initWithFrame:CGRectMake(20, 200, 300, 40)];
        [self.view addSubview:self.showLab];
        self.showLab.backgroundColor = [UIColor redColor];
        
        [self RAC_define];
        
        [self RAC_KVO];
        
        [self RAC_RACTuple];
    }
    
    //RAC宏
    -(void)RAC_define{
        RAC(self.showLab, text) = self.textF.rac_textSignal;
        /*
        [self.textF.rac_textSignal subscribeNext:^(id x) {
            self.showLab.text = x;
        }];
         */
    }
    
    -(void)RAC_KVO{
        [RACObserve(self.showLab, text) subscribeNext:^(id x) {
            NSLog(@"KVO监听文本的变化%@", x);
         }];
    }
    
    
    -(void)CyclicReferences{
        /*
        @weakify(self);
        @strongify(self);
         */
    }
    
    
    /*
     * 元祖
     * 快速包装一个元组
     * 把包装的类型放在宏的参数里面,就会自动包装
     */
    -(void)RAC_RACTuple{
        RACTuple *tuple = RACTuplePack(@1,@2,@4);
        // 宏的参数类型要和元祖中元素类型一致, 右边为要解析的元祖。
        RACTupleUnpack_(NSNumber *num1, NSNumber *num2, NSNumber * num3) = tuple;// 4.元祖
        // 快速包装一个元组
        // 把包装的类型放在宏的参数里面,就会自动包装
        NSLog(@"%@ %@ %@", num1, num2, num3);
    }
    
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        [self.view endEditing:YES];
    }
    
    -(void)dealloc{
        NSLog(@"%s",__FUNCTION__);
    }
    @end
    

    3.发送验证码

    #import "Demo.h"
    #import <ReactiveObjC.h>
    
    @interface Demo ()
    @property (nonatomic,assign)int time;
    @property (nonatomic,strong) RACDisposable *disposable;
    @end
    
    @implementation Demo
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(20, 100, 100, 60)];
        [btn setBackgroundColor:[UIColor redColor]];
        [btn setTitle:@"发送验证码" forState:UIControlStateNormal];
        [btn  addTarget:self action:@selector(reSendCode:) forControlEvents:UIControlEventTouchUpInside];
        [self.view addSubview:btn];
    }
    
    -(void)reSendCode:(UIButton*)sender{
        self.time = 15;
        @weakify(self);
        self.disposable = [[RACSignal interval:1.0 onScheduler:[RACScheduler mainThreadScheduler]]  subscribeNext:^(NSDate * _Nullable x) {
            @strongify(self);
            self.time--;
            NSString *btnText = self.time >0 ? [NSString stringWithFormat:@"%ds",self.time]:@"发送验证码";
            [sender setTitle:btnText forState:(UIControlStateNormal)];
            if(self.time>0){
                sender.enabled = NO;
            }else{
                sender.enabled = YES;
                [self.disposable dispose];//在我们取消订阅的那一刹那,帮我们打断了循环引用
            }
        }];
    }
    
    -(void)dealloc{
        NSLog(@"%s",__FUNCTION__);
    }
    @end
    

    友情链接:

    相关文章

      网友评论

          本文标题:RAC一些常见用法(五)

          本文链接:https://www.haomeiwen.com/subject/krielqtx.html