ios – 使用Reactive Cocoa组合多个信号不起作用

ios – 使用Reactive Cocoa组合多个信号不起作用,第1张

概述我正在学习本教程: http://www.raywenderlich.com/62699/reactivecocoa-tutorial-pt1.它适用于用户名和密码字段. 我正在尝试创建包含三个字段的注册表单:email,password,confirmPassword. 我已经验证了电子邮件地址(完美地工作) 我已经验证了这样的密码: 密码至少应为6个字符,密码和confirmPassword必 我正在学习本教程: http://www.raywenderlich.com/62699/reactivecocoa-tutorial-pt1.它适用于用户名和密码字段.

我正在尝试创建包含三个字段的注册表单:email,password,confirmPassword.

我已经验证了电子邮件地址(完美地工作)
我已经验证了这样的密码:

密码至少应为6个字符,密码和confirmPassword必须相同.

这是我的代码:

RACSignal *valIDEmailSignal =[emailTextFIEld.rac_textSignal map:^ID(Nsstring *text) {     return @([text isValIDEmailAddress]); }];RACSignal *valIDPasswordSignal =[passwordTextFIEld.rac_textSignal map:^ID(Nsstring *text) {     return @([text isEqualToString:self.confirmPasswordTextFIEld.text] && text.length >5); }];RACSignal *valIDConfirmPasswordSignal =[confirmPasswordTextFIEld.rac_textSignal map:^ID(Nsstring *text) {     return @([text isEqualToString:self.passwordTextFIEld.text] && text.length >5 ); }];[[valIDEmailSignal  map:^ID(NSNumber *emailValID) {      return [emailValID boolValue] ? [UIcolor greencolor] : [UIcolor redcolor];  }] subscribeNext:^(UIcolor *color) {     emailTextFIEld.layer.bordercolor=[color CGcolor];     emailTextFIEld.layer.borderWIDth= 1.0f; }];[[valIDPasswordSignal  map:^ID(NSNumber *passwordValID) {      return [passwordValID boolValue] ? [UIcolor greencolor] : [UIcolor redcolor];  }] subscribeNext:^(UIcolor *color) {     passwordTextFIEld.layer.bordercolor=[color CGcolor];     passwordTextFIEld.layer.borderWIDth= 1.0f;     confirmPasswordTextFIEld.layer.bordercolor=[color CGcolor];     confirmPasswordTextFIEld.layer.borderWIDth= 1.0f; }];[[valIDConfirmPasswordSignal  map:^ID(NSNumber *passwordValID) {      return [passwordValID boolValue] ? [UIcolor greencolor] : [UIcolor redcolor];  }] subscribeNext:^(UIcolor *color) {     passwordTextFIEld.layer.bordercolor=[color CGcolor];     passwordTextFIEld.layer.borderWIDth= 1.0f;     confirmPasswordTextFIEld.layer.bordercolor=[color CGcolor];     confirmPasswordTextFIEld.layer.borderWIDth= 1.0f; }];RACSignal *signUpActiveSignal =[RACSignal combineLatest:@[valIDEmailSignal,valIDPasswordSignal,valIDConfirmPasswordSignal]                  reduce:^ID(NSNumber *emailValID,NSNumber *passwordValID,NSNumber *confirmPasswordValID) {                      return @([emailValID boolValue] && [passwordValID boolValue] && [confirmPasswordValID boolValue]);                  }];[signUpActiveSignal subscribeNext:^(NSNumber *signupActive) {    NSLog(@"sign up button enabled : %hhd",[signupActive boolValue]);    _signUpbutton.enabled = [signupActive boolValue];}];

在这里,如果我只接受emailValID的值,则在有效时发送1.但是如果我包含所有三个值,即使所有值都有效,它也总是返回0.

以下是模拟器的快照:

我只想在所有三个字段都有效时启用“注册”按钮.我还想在键盘上禁用“开始”按钮,直到验证成功.

解决方法 好的,有两件事:

您可以使用RACSignal的和帮助器使信号减少更清洁:

RACSignal *signUpActiveSignal = [[RACSignal combineLatest:@[valIDEmailSignal,valIDConfirmPasswordSignal]] and];

您还可以使用RAC宏来绑定enabled属性(示例代码使用subscribeNext而不是RAC的唯一原因是CGcolorRef不是ID类型):

RAC(self.signUpbutton,enabled) = signUpActiveSignal;

现在说这不起作用的原因.我们来看看密码字段的计算:

RACSignal *valIDPasswordSignal = [passwordTextFIEld.rac_textSignal map:^ID(Nsstring *text) {    return @([text isEqualToString:self.confirmPasswordTextFIEld.text] && text.length > 5);}];RACSignal *valIDConfirmPasswordSignal = [confirmPasswordTextFIEld.rac_textSignal map:^ID(Nsstring *text) {    return @([text isEqualToString:self.passwordTextFIEld.text] && text.length > 5);}];

每次passwordTextFIEld的文本发生更改时,都会将其与confirmPasswordTextFIEld进行比较.但它只会在passwordTextFIEld更改时检查它们是否相同,而不是在confirmPasswordTextFIEld更改时.所以让我们想象下面的场景,忽略(现在)长度要求:

------------------- initial state -------------------           -------------password: |             |   passwordValID: YES           -------------           ------------- confirm: |             |   confirmValID: YES           --------------------------- user types in a password --------------           -------------password: | asdf        |   passwordValID: NO           -------------           ------------- confirm: |             |   confirmValID: YES (this will only recalculate when the confirm fIEld changes,not when the password fIEld changes)           -------------------- user types in the password confirmation -------           -------------password: | asdf        |   passwordValID: NO (this dIDn't recalculate because the contents of the password fIEld dIDn't change)           -------------           ------------- confirm: | asdf        |   confirmValID: YES           -------------

啊哈!因此,我们需要在其中任何一个发生变化时重新计算.而且,实际上,这应该是与长度分开的信号:

RACSignal *passwordsMatch = [RACSignal combineLatest:@[passwordTextFIEld.rac_textSignal,confirmPasswordTextFIEld.rac_textSignal]                                              reduce:(Nsstring *password,Nsstring *confirm) {                                                  return @([password isEqualToString:confirm]);                                              }];RACSignal *isPasswordLongEnough = [passwordTextFIEld.rac_textSignal map:^(Nsstring *text) {    return @(text.length >= 6);}];

然后我们可以把它们放在一起:

RACSignal *signUpActiveSignal = [[RACSignal combineLatest:@[valIDEmailSignal,isPasswordLongEnough,passwordsMatch]] and];

这很好,因为我们就是这样想的:“当电子邮件地址有效时,您可以登录,输入的密码足够长,密码确认字段与密码匹配.”声明!

总结

以上是内存溢出为你收集整理的ios – 使用Reactive Cocoa组合多个信号不起作用全部内容,希望文章能够帮你解决ios – 使用Reactive Cocoa组合多个信号不起作用所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1071931.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存