2015-05-18 2 views
1

Я использую MVVM архитектуру и у меня есть два сигнала:ReactiveCocoa, объединить два сигнала на кнопку включен

RACSignal *internetEnabledSignal = RACObserve(self.regWizardVehicleViewModel, internetConnectionEnabled); 
RACSignal *executingRegistrationSignal = RACObserve(self.regWizardVehicleViewModel, isExecuting); 

мне нужно, чтобы объединить и связать сигналы на кнопку включен свойства. Кнопка должна быть отключена, если соединение отсутствует или когда какой-либо метод выполняется. Я искал и искал решение, но не знаю, как комбинировать сигналы с OR. Есть ли способ сделать это? Следующий вопрос: я использую MBProgressHUD. Я хочу показать, что HUD во время выполнения моего асинхронного метода в моей модели. MBProgressHUD имеет методы show и hide, не может привязать его к свойству, например, кнопке?

ответ

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 (это еще одна причина, почему это чит).

9

Существует удобный метод, -and, который делает работу с «логическими» значением сигналами проще:

Возвращает сигнал, который относится и к каждому NSNumber в кортеже.

Чтобы получить кортеж с NSNumbers, используйте combineLatestWith: так:

RAC(self.button, enabled) =[[[executingRegistrationSignal not] 
     combineLatestWith:internetEnabledSignal] 
     and]; 
+0

Большой простой вариант использования. Я буду отмечать этот ответ как полезный, но в предыдущем ответе есть ответ на мой другой вопрос, чтобы ответ был завершен. Большое спасибо :) – Flipper

Смежные вопросы