使用 ReactiveCocoa 禁用 UIBarButtonItem

Disabling UIBarButtonItem with ReactiveCocoa

我正在尝试在满足条件时禁用我的 iOS 应用程序中的 UIBarButtonItem

所以在我的viewModel中我创建了这个信号:

-(RACSignal *)thresholdLimitReachedSignal
{
    @weakify(self);
    return [RACObserve(self, thresholdLimitReached) filter:^BOOL(id value) {
            @strongify(self);
        return self.thresholdLimitReached;
    }];
}

然后在我的 viewController 我有这个:

self.requestNewPinButton.rac_command = [[RACCommand alloc]initWithEnabled:self.viewModel.thresholdLimitReachedSignal
                                                                   signalBlock:^RACSignal *(id input) {

           [self.viewModel.requestNewPinSignal subscribeNext:^(id x) {

                   //do some stuff here
           }];
           return [RACSignal empty];
       }];

因此 UIBarButtonItem 被触发并触发 requestNewPinSignal,效果很好。然后我标记 thresholdLimitReached 导致触发 thresholdLimitReachedSignal - 一切正常。但是,该按钮并没有被禁用,我不确定为什么?无论我在 thresholdLimitReachedSignal 方法中手动将布尔值设置为 true 还是 false - 按钮都保持启用状态!

如果我手动订阅thresholdLimitReachedSignal 像这样:

[self.viewModel.thresholdLimitReachedSignal subscribeNext:^(id x) {
    self.requestNewPinButton.enabled = NO;
}];

然后按钮被禁用没问题。我想以某种方式将此信号与 requestSignal 结合起来 - 我认为 initWithEnabled:signalBlock 是这样做的吗?

[RACObserve(self, thresholdLimitReached) filter:^BOOL(id value) {
        @strongify(self);
    return self.thresholdLimitReached;
}];

您正在过滤 thresholdLimitReachedSignal,因此它只会 returns YES,因此您的按钮将始终处于启用状态。对于初学者,您可以这样重写并避免 @weakify/@strongify:

[RACObserve(self, thresholdLimitReached) filter:^BOOL(NSNumber *thresholdLimitReached) {
    return thresholdLimitReached.boolValue;
}];

但是不要那样做:如果你使用它作为启用信号,它需要是一个布尔信号,当它应该被启用时发送 YES 并且当它应该被启用时发送 NO它应该被禁用。

假设您希望在达到阈值时禁用按钮,您需要这样的东西:

[[RACCommand alloc] initWithEnabled:[RACObserve(self.viewModel, thresholdLimitReached) not]
                        signalBlock:...];