注意:我使用ReactiveCocoaLayout进行基于信号的动画。
我有一个UILabel,我想绑定到视图模型上的NSString *属性。
RACSignal* statusSignal = [RACObserve(self, viewModel.status) distinctUntilChanged];
足够简单。但是,现在我想添加一些奇特的动画。当status
发生变化时,我想要连续发生的事情:
alpha
从1 - > 0)alpha
中的1 - > 0)这是我迄今为止能够提出的:
RACSignal* statusSignal = [RACObserve(self, viewModel.status) distinctUntilChanged];
// An animation signal that initially moves from (current) -> 1 and moves from (current) -> 0 -> 1 after that
RACSignal* alphaValues = [[statusSignal flattenMap:^RACStream *(id _) {
// An animation signal that moves towards a value of 1
return [[[RACSignal return:@1]
delay:animationDuration]
animateWithDuration:animationDuration];
}] takeUntilReplacement:[[statusSignal skip:1] flattenMap:^RACStream *(id _) {
// An animation signal that moves towards a value of 0, waits for that to complete, then moves towards a value of 1
return [[[RACSignal return:@(0)]
animateWithDuration:animationDuration]
concat:[[[RACSignal return:@1]
delay:animationDuration]
animateWithDuration:animationDuration]];
}]];
RAC(self, statusLabel.alpha) = alphaValues;
// The initial status should be applied immediately. Combined with the initial animation logic above, this will nicely fade in the first
// status. Subsequent status changes are delayed by [animationDuration] in order to allow the "fade" animation (alpha from 1 -> 0) to
// finish before the text is changed.
RAC(self, statusLabel.text) = [[statusSignal take:1]
concat:[[statusSignal delay:animationDuration]
deliverOn:[RACScheduler mainThreadScheduler]]];
这很有效,但我不能感觉它有点...... 工程。大部分复杂性来自我的基本情况 - 初始文本应该淡入,随后的文本更改应淡出然后淡入。
有关如何简化或优化的任何想法?
答案 0 :(得分:1)
我还没有使用过RCL,所以如果我错误地使用了-animateWithDuration:
,请告诉我。
首先,我定义了一个发送@YES
而不是第一个状态的信号,以及@NO
而不是所有后续状态。这是通过利用-bind:
运算符来完成的,该运算符允许通过块捕获自定义每用户变量。
RACSignal *isFirstStatus = [statusSignal bind:^{
__block BOOL first = YES;
return ^(id _, BOOL *stop) {
BOOL isFirst = first;
first = NO;
return [RACSignal return:@(isFirst)];
};
}];
接下来,将isFirstStatus
与+if:then:else:
放在一起以开始初始动画信号,然后切换到永久动画信号。
RAC(self, statusLabel.alpha) = [[RACSignal
if:isFirstStatus
// Initially, an animation signal to 1.
then:[RACSignal return:@1]
// Subsequently, an animation signal to 0, then, to 1.
else:[[[RACSignal return:@1] delay:animationDuration] startWith:@0]]
animateWithDuration:animationDuration];
我已经找到了一种通过完成动画来处理带内文本属性更新的方法,但没有找到我喜欢的内容。如果还没有一种好的方法,这可能是为这种类型的场景添加运算符到RCL的机会。
答案 1 :(得分:0)
以类似的方式实施解决方案。
[RACObserve(self, curChannel) subscribeNext:^(NSNumber* v) {
BGChannel* ch = self.model.subscriptions[v.intValue];
[UIView transitionWithView:self.channelLabel duration:0.75 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
self.channelLabel.text = ch.name;
} completion:nil];
}];