iOS 用RAC实现简单的登录逻辑和颜色控制器,附代码

下面两个demo的demo地址

iOS RAC下对应的的Target Action模式、代理模式和观察者模式

Demo1:当输入的用户名不为空且密码长度大于6时,登录按钮可点,否则不可点

分析:将两个输入框转化成信号量,并进行绑定,然后使用map进行映射返回新的信号量,用RAC()绑定在button的enable属性上,

- (void)viewDidLoad {
    [super viewDidLoad];
    
    /*
     将TextField的输入转化为信号量
     */
    RACSignal *userNameSignal = self.userNameTF.rac_textSignal;
    RACSignal *psdSignal = self.psdTF.rac_textSignal;
    /*
     合并两个输入框的信号量,并使用map对信号量返回值进行映射使其返回bool值,
     */
    RACSignal *bigSignal = [[RACSignal combineLatest:@[userNameSignal,psdSignal]] map:^id _Nullable(RACTuple * _Nullable value) {
        RACTupleUnpack(NSString *username , NSString *psd) = value;
        //@()将值变量装箱成对象
        return @([username length]>0 && [psd length]>6);
    }];
    /*
     使用RAC将一个信号量绑定在一个属性上
     */
    RAC(self.loginBtn, enabled) = bigSignal;
}

使用到的RAC知识点:

rac_textSignal--监听文本框文字改变,对应UITextField 、UItextView

combineLatest--将多个信号量合并,返回一个新的信号量,当每一个子信号量都有过一次sendNext时,子信号触发才会才会触发合并信号并返回每一个子信号的最新值。

map--把一个信号量的内容映射成新的内容。

RACTupleUnpack--将RACTuple(元祖类)解包成对应的数据

RAC(Target,Keypath)--将一个对象的某个属性绑定到一个信号量对应的内容上


Demo2:三个UISlider和三个UITextField分别对应R G B颜色值,当滑动滑块或者输入框输入时,改变当前view的背景颜色,且滑块和输入框之间可以互相改变对方的值。

分析:首先将每一对滑块和输入框都转成管道信号,然后对管道进行双向绑定,输出新的信号,共得到三个新的信号量分别对应RGB的颜色值,将R G B三个新的信号进行合并返回的信号用RAC()绑定到view的backgroundcolor的属性上。

- (void)viewDidLoad {
    [super viewDidLoad];
    
    RACSignal *redSignal =  [self bindSlider:_redSlider withTF:_redTF];
    RACSignal *greenSignal =  [self bindSlider:_greenSlider withTF:_greenTF];
    RACSignal *blueSignal =  [self bindSlider:_blueSlider withTF:_blueTF];
    
    RAC(self.showView,backgroundColor) = [[RACSignal combineLatest:@[redSignal , greenSignal , blueSignal]] map:^id _Nullable(RACTuple * _Nullable value) {
        return [UIColor colorWithRed:[value[0] floatValue] green:[value[1] floatValue] blue:[value[2] floatValue] alpha:1];
    }];
    
}

/*
 绑定slider和输入框
 */
- (RACSignal *)bindSlider:(UISlider *)slider withTF:(UITextField *)TF
{
    RACChannelTerminal *sliderChannel = [slider rac_newValueChannelWithNilValue:nil];
    RACChannelTerminal *tfChannel = TF.rac_newTextChannel;
    //执行一次,因为combineLatest需要合并的信号中每个至少sdnNext一次才会触发订阅
    RACSignal *oneSignal = [TF.rac_textSignal take:1];
    
    [tfChannel subscribe:sliderChannel];
    [[sliderChannel map:^id _Nullable(id  _Nullable value) {
        return [NSString stringWithFormat:@"%.2f" , [value floatValue]];
    }] subscribe:tfChannel];
    
    //merge将多个信号合并成一个,订阅的话只有一个返回值
    return [[sliderChannel merge:tfChannel]merge:oneSignal];;
}

第二个demo使用到的RAC知识点:

RACChannelTerminal--RACSignal的子类,通道终端,可以将两个RACChannelTerminal进行双向绑定

rac_newValueChannelWithNilValue--获取UISlider的通道终端,是RAC给UISlider添加的一个分类

rac_newTextChannel--获取UITextField的通道终端,也是一个分类

take:(NSinteget)count--使信号量触发多少次

subscribe--对两个通道终端进行绑定

merge--把多个信号量合并为一个新信号量,当任何一个子信号量触发时,都会触发这个新信号量,但是返回值只有被触发的子信号量的返回值。

PS:注意merge和combineLatest的区别,两个都是将多个信号量合并,但是merge是只要有子信号量触发就会返回该子信号量的内容,而combineLatest是当子信号量触发时,只有当其他信号量都触发过sendNext才会触发,并且是返回所有子信号量的内容。

猜你喜欢

转载自blog.csdn.net/yingbi2014/article/details/79926165
今日推荐