ReactiveCocoa,在启用按钮时组合两个信号

Fli*_*per 1 objective-c mvvm ios reactive-cocoa

我正在使用MVVM架构,我有两个信号:

RACSignal *internetEnabledSignal = RACObserve(self.regWizardVehicleViewModel, internetConnectionEnabled);
RACSignal *executingRegistrationSignal = RACObserve(self.regWizardVehicleViewModel, isExecuting);
Run Code Online (Sandbox Code Playgroud)

我需要在启用按钮的属性上组合和绑定信号.如果没有任何连接或某些方法正在执行时,需要禁用Button.我正在寻找解决方案,但我不知道如何将信号与OR结合起来.有没有办法做到这一点?接下来的问题是:我正在使用MBProgressHUD.我想在我的模型中执行我的异步方法时显示HUD.MBProgressHUD有显示和隐藏方法,无法将其绑定到按钮启用的属性?

Mic*_*uba 9

有一种方便的方法,-and可以更容易地使用"布尔"值信号:

返回一个信号,该信号对元组中的每个NSNumber应用AND.

要获得元组NSNumbers,请使用combineLatestWith:如下:

   RAC(self.button, enabled) =[[[executingRegistrationSignal not] 
        combineLatestWith:internetEnabledSignal]
         and];
Run Code Online (Sandbox Code Playgroud)


Lot*_*lla 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;
Run Code Online (Sandbox Code Playgroud)

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]
]];
Run Code Online (Sandbox Code Playgroud)

这有点作弊,我们正在利用RAC对这些信号的热切期望来解决副作用,但如果你是一个实用主义者而不是像我这样迂腐的理想主义者,你可能不介意.

这段代码发生了什么,我们要求RAC在我们提供的数组中的每一个信号触发后执行给定的选择器,所以它很像combineLatest:.我们正在使用,mapReplace:因为它将使用该信号作为(BOOL)animated参数(这是为什么它是作弊的另一个原因).