Объединение сигналов, но просто подписаться, когда первый изменится
Я хочу объединить rac_signalForControlEvent
на UIButton с некоторыми комбинированными сигналами textFields, например, так:
[[[[self.loginButton rac_signalForControlEvents:UIControlEventTouchUpInside]
combineLatestWith:textFieldsCombinedSignal]
filter:^BOOL(RACTuple *signals) {
return ((UIButton *)[signals first]).highlighted;
}] subscribeNext:^(RACTuple *signals) {
if ([signals.second boolValue])
{
[self doLogin];
}
else
{
[self error];
}
}];
Но таким образом, я должен отфильтровать состояние кнопки, в противном случае subscribeNext:
блок запускается каждый раз, когда изменяются некоторые текстовые поля (textFieldsCombinedSignal
).
Я хотел бы достичь этого без необходимости фильтровать состояние выделенной кнопки (в конце концов, я использую ReactiveCocoa, чтобы минимизировать состояние, и я не чувствую, что это правильный способ сделать то, что я пытаюсь сделать).
2 ответа
Если вы хотите последовательность нажатий кнопок, а затем последний из вашего комбинированного сигнала текстового поля, это может быть так же просто, как с помощью -flattenMap:
:
[[[self.loginButton
rac_signalForControlEvents:UIControlEventTouchUpInside]
flattenMap:^(id _) {
return [textFieldsCombinedSignal take:1];
}]
subscribeNext:^…];
Однако из того, что вы описали, это похоже на классический случай RACCommand
, Как этот код, так и оригинальный код, позволяют пользователю дважды нажать кнопку входа в систему и инициировать одновременный вход в систему.
Перед показом RACCommand
Я сделаю пару предположений о вашем коде. Только от имени, textFieldsCombinedSignal
это может быть сигнал, который отправляет кортеж строк, но при вашем использовании это выглядит так, как будто это действительно проверочный сигнал, который отправляет ДА / НЕТ. Я возьму последний и переименую его в loginIsValid
, Я также предполагаю, что -doLogin
является синхронным с целью этого примера.
Сейчас RACCommand
:
self.loginButton.rac_command = [[RACCommand alloc] initWithEnabledSignal:loginIsValid signalBlock:^(id _) {
return [RACSignal defer:^{
[self doLogin];
return [RACSignal empty];
}];
}];
Для этого нужно включить / отключить кнопку входа в систему на основе последнего значения, отправленного на loginIsValid
, Когда включено, нажатие на кнопку приведет к -doLogin
будет вызвана, и кнопка будет отключена во время процесса входа в систему, предотвращая одновременные входы в систему.
Похоже, вы просто хотите попробовать textFieldsCombinedSignal
всякий раз, когда кнопка нажата. Попробуйте использовать -sample:
:
RACSignal *buttonSignal = [self.loginButton rac_signalForControlEvents:UIControlEventTouchUpInside];
[[textFieldsCombinedSignal sample:buttonSignal] subscribeNext:^(RACTuple *combinedTextFields) {
// do stuff with combinedTextFields
}];