RAC一些常见用法(五)

本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

友情链接:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,458评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,454评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,171评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,062评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,440评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,661评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,906评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,609评论 0 200
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,379评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,600评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,085评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,409评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,072评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,088评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,860评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,704评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,608评论 2 270

推荐阅读更多精彩内容