ReactiveCocoa - UIPickerView的didSelect RAC信号不执行的问题

一、前言

在查看本文前,如果你对ReactiveCocoa不是很熟悉,请移步到以下位置补脑吧!

ReactiveCocoa入门教程 

最快让你上手ReactiveCocoa之基础篇

最近在学习RAC(ReactiveCocoa太长了,大佬们简称为RAC),想把RAC运用到一个项目中去(是一个智能APP的项目),由于是我自己的项目,UI设计图我都发布出来了,有兴趣的可以自己去下载

从零开始深入制作智能控制APP(一)

二、场景重现

我们通过一个很简单的UIDEMO来展现pickView的情况,笔者封装了一个继承于UIPickerView的类-ListPickerView,便于重现场景 你可以通过下面的地址去下载集成好的工程项目

 [FJRACDemo]

首先笔者介绍下demo的功能,打开ViewController 可以看到,有一个textField的输入控件,还有一个postBtn的提交按钮,textField的输入源被修改成为了pickView,通过用户的选择来更改textField的text值,我们要实现用户必须使用pickView选择 更改了textField的值,textField的背景颜色为浅灰色,否则为红色,textField无值得时候提交按钮(postBtn)不能点击。下面看下demo的运行图:

ReactiveCocoa - UIPickerView的didSelect RAC信号不执行的问题-iOS技术博客,iOS开发,iOS技术交流,iOS开发经验

运行项目我们发现以下问题

  • 在第一次选中pickView的值的时候,textField背景并没有更改

  • 在第二次去选中的时候,textFiedld的背景颜色才更改

  • 第一次选中的时候,postBtn是不可点击的状态

  • 在第二次去选中的时候,postBtn才可以点击

//设置RAC,木有选择任何字符则返回no
    RACSignal *textSignal = [textField.rac_textSignal map:^id(NSString *text) {
        
        
        return text.length != 0 ? @(YES) : @(NO);
        
    }];
    
    RAC(textField,backgroundColor) = [textSignal map:^id(NSNumber *valid) {
      
         return [valid boolValue] ? [UIColor colorWithRed:1.000 green:0.998 blue:0.962 alpha:0.8]:[UIColor redColor];
        
    }];
    
    
    RACSignal *postSignal = [RACSignal combineLatest:@[textSignal] reduce:^id(NSNumber *valid){
        
        return valid;
        
        
    }];
    
    
    [postSignal  subscribeNext:^(NSNumber *postActive) {
       
        
        postBtn.enabled = [postActive boolValue];
        
    }];

笔者尝试在 "return text.length != 0 ? @(YES) : @(NO);" 打断点测试发现第一次选择的时候根本就不执行,笔者通过百度\谷歌找了很多方法,都木有看到解决的方案,于是去请教笔者的老师(本人是培训机构培训出来的,曾经在培训的一个[iOS女大神老师]可以去她博客看看,都是干货)提醒了我,只有在textFiedld输入的时候才触发信号,于是我打开"rac_textSignal"里面看了下RAC的源码

- (RACSignal *)rac_textSignal {
    @weakify(self);
    return [[[[[RACSignal
        defer:^{
            @strongify(self);
            return [RACSignal return:self];
        }]
        concat:[self rac_signalForControlEvents:UIControlEventEditingChanged | UIControlEventEditingDidBegin]]
        map:^(UITextField *x) {
            return x.text;
        }]
        takeUntil:self.rac_willDeallocSignal]
        setNameWithFormat:@"%@ -rac_textSignal", self.rac_description];
}

concat:[self rac_signalForControlEvents:UIControlEventEditingChanged | UIControlEventEditingDidBegin]]

RAC是添加了"UIControlEventEditingChanged"和"UIControlEventEditingDidBegin"这2个事件的监听,textField的输入源的pickView是直接更改了textField的值,并不会影响这2个的值,于是笔者尝试把代码更改为以下

- (RACSignal *)rac_textSignal {
    @weakify(self);
    return [[[[[RACSignal
        defer:^{
            @strongify(self);
            return [RACSignal return:self];
        }]
        concat:[self rac_signalForControlEvents:UIControlEventEditingChanged | UIControlEventEditingDidBegin|UIControlEventEditingDidEnd]]
        map:^(UITextField *x) {
            return x.text;
        }]
        takeUntil:self.rac_willDeallocSignal]
        setNameWithFormat:@"%@ -rac_textSignal", self.rac_description];
}

笔者增加了 "UIControlEventEditingDidEnd"事件的监听,然后我们在运行下项目你会发现不管是第一次还是啥时候点击都不会有任何的问题,完全符合我们的功能要求。

1、欢迎来到Biny博客!

2、专注于iOS移动端开发,欢迎广大大师们、大神们吐槽.....

3、欢迎友情链接 网站名:Biny博客 网址:http://www.Xcode.cc 描述:Biny博客是一个技术博客,文章主要包含移动互联IOS相关内容,记录一些在IOS编码过程中遇到的坑和看到大神们记录下的经验,以便查阅。


赞一个 (2)
分享到: +More

评论 沙了个发

换个身份

取消评论