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];