在我的应用程序中,我有一个信号,它通过flattenMap
触发一些异步网络活动。我想在网络活动进行时显示加载指示符。
我目前的解决方案很好用:
[[[[self.signInButton
rac_signalForControlEvents:UIControlEventTouchUpInside]
doNext:^(id x) {
// show the loading indicator as a side-effect
self.loadingIndicator.hidden = NO;
}]
flattenMap:^id(id x) {
return [self doSomethingAsync];
}]
subscribeNext:^(NSNumber *result) {
// hide the indicator again
self.loadingIndicator.hidden = YES;
// do something with the results
}];
这样可行,但是我想更改上面的代码,以便可以通过信号设置加载指示符的hidden
属性。
这可能吗?
在我的应用程序的其他地方,我有更复杂的要求,其中元素的可见性取决于几个不同的“事件”,能够通过信号组合这些将更好。
答案 0 :(得分:13)
RACCommand是针对这个用例量身定制的,通常会产生比替代方案更简单的代码:
@weakify(self);
RACCommand *signInCommand = [[RACCommand alloc] initWithSignalBlock:^(id _) {
@strongify(self);
return [self doSomethingAsync];
}];
self.signInButton.rac_command = signInCommand;
// Show the loading indicator while signing in.
RAC(self.loadingIndicator, hidden) = [signInCommand.executing not];
答案 1 :(得分:2)
看起来您的信号是:当signInButtonSignal
或resultSignal
发送值时,反转hidden
的最后一个值。这很容易。
[[[hiddenSig replayLast] not] sample:[RACSignal merge:@[signInButtonSignal, resultSignal]];
我正在使用与你的情况类似的情况。把它包装成一个运算符可能会很好:
- (RACSignal *)toggle:(RACSignal *)toggler
{
return [[[self replayLast] not] sample:toggler];
}
然后你就是
[hiddenSig toggle:[RACSignal merge:@[signInButtonSignal, resultSignal]]];
另一种可能性是类方法,将状态绑定到映射块:
+ (RACSignal *)toggle:(RACSignal *)toggler initially:(BOOL)initial
{
__block BOOL currVal = initial;
return [[toggler map:^id (id _) {
currVal = !currVal;
return @(currVal);
}] startWith:@(initial)];
}
然后
[RACSignal toggle:[RACSignal merge:@[signInButtonSignal, resultSignal]]
initially:NO];
答案 2 :(得分:2)
answer from Josh帮助了很多,但最后我找到了一个更简单的解决方案。简单地将管道分成两个信号,一个用于按下按钮,另一个用于后续的异步活动。然后我合并了两个以给出一个信号,我曾经将其绑定到loadingIndicator
的{{1}}属性:
hidden