Объединение сигналов, но просто подписаться, когда первый изменится

Я хочу объединить 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
}];
Другие вопросы по тегам