ReactiveCocoa,在启用的按钮上组合两个信号
ReactiveCocoa, combine two signals on button enabled
我正在使用 MVVM 架构,我有两个信号:
RACSignal *internetEnabledSignal = RACObserve(self.regWizardVehicleViewModel, internetConnectionEnabled);
RACSignal *executingRegistrationSignal = RACObserve(self.regWizardVehicleViewModel, isExecuting);
我需要在启用的按钮上组合和绑定信号 属性。如果没有任何连接或正在执行某些方法,则需要禁用按钮。我一直在寻找解决方案,但我不知道如何将信号与 OR 组合。有什么办法吗?下一个问题是:我正在使用 MBProgressHUD。我想在我的模型中执行我的异步方法时显示该 HUD。 MBProgressHUD 有显示和隐藏方法,不能将它绑定到 属性 之类的启用按钮?
如果我没有误会你的意思,那么使用 combineLatest:reduce:
应该可以轻松实现该功能,例如:
RACSignal * enabledSignal =
[RACSignal combineLatest:@[internetEnabledSignal, executingRegistrationSignal]
reduce:^id(NSNumber * internetEnabled, NSNumber * isExecuting) {
return @(internetEnabled.boolValue && !isExecuting.boolValue);
}].distinctUntilChanged;
RAC(self.button, enabled) = enabledSignal;
combineLatest:reduce:
在所有信号至少触发一次之前不会发送任何下一个事件,因此请牢记这一点。
编辑:请参阅 Michał 的回答,通过便捷的方法获得更酷的解决方案。
至于你的另一个问题,我对 MBProgressHUD 不是很熟悉,但这应该可以解决问题:
[self.hud rac_liftSelector:@selector(show:) withSignalsFromArray:@[
[enabledSignal ignore:@NO]
]];
[self.hud rac_liftSelector:@selector(hide:) withSignalsFromArray:@[
[[enabledSignal ignore:@YES] mapReplace:@YES]
]];
这有点作弊,我们正在利用 RAC 对这些信号的热切订阅来激发副作用,但如果您是实用主义者而不是像我这样迂腐的理想主义者,您可能不介意。
这段代码发生的事情是我们要求 RAC 在我们提供的数组中的每个信号触发后执行给定的选择器,所以它很像 combineLatest:
。我们使用 mapReplace:
因为它将使用该信号作为 (BOOL)animated
参数(这是作弊的另一个原因)。
有一种方便的方法,-and
可以更轻松地处理 "boolean" 值信号:
Returns a signal that applies AND to each NSNumber in the tuple.
要使用 NSNumbers
获取元组,请像这样使用 combineLatestWith:
:
RAC(self.button, enabled) =[[[executingRegistrationSignal not]
combineLatestWith:internetEnabledSignal]
and];
我正在使用 MVVM 架构,我有两个信号:
RACSignal *internetEnabledSignal = RACObserve(self.regWizardVehicleViewModel, internetConnectionEnabled);
RACSignal *executingRegistrationSignal = RACObserve(self.regWizardVehicleViewModel, isExecuting);
我需要在启用的按钮上组合和绑定信号 属性。如果没有任何连接或正在执行某些方法,则需要禁用按钮。我一直在寻找解决方案,但我不知道如何将信号与 OR 组合。有什么办法吗?下一个问题是:我正在使用 MBProgressHUD。我想在我的模型中执行我的异步方法时显示该 HUD。 MBProgressHUD 有显示和隐藏方法,不能将它绑定到 属性 之类的启用按钮?
如果我没有误会你的意思,那么使用 combineLatest:reduce:
应该可以轻松实现该功能,例如:
RACSignal * enabledSignal =
[RACSignal combineLatest:@[internetEnabledSignal, executingRegistrationSignal]
reduce:^id(NSNumber * internetEnabled, NSNumber * isExecuting) {
return @(internetEnabled.boolValue && !isExecuting.boolValue);
}].distinctUntilChanged;
RAC(self.button, enabled) = enabledSignal;
combineLatest:reduce:
在所有信号至少触发一次之前不会发送任何下一个事件,因此请牢记这一点。
编辑:请参阅 Michał 的回答,通过便捷的方法获得更酷的解决方案。
至于你的另一个问题,我对 MBProgressHUD 不是很熟悉,但这应该可以解决问题:
[self.hud rac_liftSelector:@selector(show:) withSignalsFromArray:@[
[enabledSignal ignore:@NO]
]];
[self.hud rac_liftSelector:@selector(hide:) withSignalsFromArray:@[
[[enabledSignal ignore:@YES] mapReplace:@YES]
]];
这有点作弊,我们正在利用 RAC 对这些信号的热切订阅来激发副作用,但如果您是实用主义者而不是像我这样迂腐的理想主义者,您可能不介意。
这段代码发生的事情是我们要求 RAC 在我们提供的数组中的每个信号触发后执行给定的选择器,所以它很像 combineLatest:
。我们使用 mapReplace:
因为它将使用该信号作为 (BOOL)animated
参数(这是作弊的另一个原因)。
有一种方便的方法,-and
可以更轻松地处理 "boolean" 值信号:
Returns a signal that applies AND to each NSNumber in the tuple.
要使用 NSNumbers
获取元组,请像这样使用 combineLatestWith:
:
RAC(self.button, enabled) =[[[executingRegistrationSignal not]
combineLatestWith:internetEnabledSignal]
and];