我使用的是MVVM架构,我有两个信号:
RACSignal *internetEnabledSignal = RACObserve(self.regWizardVehicleViewModel, internetConnectionEnabled);
RACSignal *executingRegistrationSignal = RACObserve(self.regWizardVehicleViewModel, isExecuting);
我需要在启用按钮的属性上组合和绑定信号。如果没有任何连接或某些方法正在执行时,需要禁用Button。我正在寻找解决方案,但我不知道如何将信号与OR结合起来。有没有办法做到这一点?下一个问题是:我正在使用MBProgressHUD。我想在我的模型中执行我的异步方法时显示HUD。 MBProgressHUD有显示和隐藏方法,不能将它绑定到启用按钮的属性吗?
答案 0 :(得分:9)
有一种方便的方法,-and
可以使用" boolean"价值信号更容易:
返回一个信号,该信号对元组中的每个NSNumber应用AND。
要获得NSNumbers
的元组,请使用combineLatestWith:
,如下所示:
RAC(self.button, enabled) =[[[executingRegistrationSignal not]
combineLatestWith:internetEnabledSignal]
and];
答案 1 :(得分:5)
如果我没有误解你,那么使用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
参数(这是欺骗的另一个原因)。