Note: I'm using ReactiveCocoaLayout for signal-based animations.
I have a UILabel that I'd like to bind to a NSString* property on a view model.
RACSignal* statusSignal = [RACObserve(self, viewModel.status) distinctUntilChanged];
Simple enough. However, now I'd like to add some fancy animations. What I want to happen, serially, when the status
changes:
- Fade the label out (
alpha
from 1 -> 0) - Apply the new text to the UILabel
- Fade the label in (
alpha
from 1 -> 0)
This is what I've been able to come up with so far:
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]]];
This works, but I can't shake the feeling that it's a little... engineered. Much of the complication comes from my base case - The initial text should just fade in, subsequent text changes should fade out then fade in.
Any thoughts on how to simplify or optimize?