Created
June 23, 2013 06:37
-
-
Save nevyn/5844046 to your computer and use it in GitHub Desktop.
How to wait for multiple different-timed animations in a generic manner? A reply to http://inessential.com/2013/06/22/technical_notes_on_vespers_full-scree .
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "TCAppDelegate.h" | |
// Let's use https://github.com/nevyn/SPAsync | |
#import <SPAsync/SPTask.h> | |
@interface UIView (SPTaskAnimations) | |
// Category that returns an abstraction representing an asynchronous operation, rather than just a raw block. We can use this abstraction later to compose multiple of them. | |
+ (SPTask*)task_animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations; | |
@end | |
static UIView *coloredView(UIColor *color, CGPoint position); | |
@implementation TCAppDelegate | |
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions | |
{ | |
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; | |
self.window.backgroundColor = [UIColor whiteColor]; | |
[self.window makeKeyAndVisible]; | |
UIView *red = coloredView([UIColor redColor], CGPointMake(60, 30)); | |
UIView *gre = coloredView([UIColor greenColor], CGPointMake(20, 200)); | |
UIView *blu = coloredView([UIColor blueColor], CGPointMake(220, 40)); | |
[self.window addSubview:red]; | |
[self.window addSubview:gre]; | |
[self.window addSubview:blu]; | |
// Let's wait for multiple things to finish. | |
[[[SPTask awaitAll:@[ | |
// Create three different asynchronous operations. | |
[UIView task_animateWithDuration:.9 delay:1 options:0 animations:^{ | |
red.center = CGPointMake(170, 180); | |
}], | |
[UIView task_animateWithDuration:.4 delay:1 options:0 animations:^{ | |
gre.center = CGPointMake(120, 220); | |
}], | |
[UIView task_animateWithDuration:1.5 delay:1 options:0 animations:^{ | |
blu.center = CGPointMake(220, 220); | |
}], | |
// Add a callback to when all three tasks have finished. Make that callback return yet another thing to wait for (a fade-out) | |
]] chain:^SPTask *(id value) { | |
return [UIView task_animateWithDuration:.5 delay:1.5 options:0 animations:^{ | |
red.alpha = gre.alpha = blu.alpha = 0; | |
}]; | |
// Add a callback to when that one has finished as well. | |
} on:dispatch_get_main_queue()] addCallback:^(id value) { | |
NSLog(@"All done!"); | |
}]; | |
// We could have accomplished the same thing by using NSOperation and adding dependencies between them. I'm not sure which one I prefer. | |
return YES; | |
} | |
@end | |
@implementation UIView (SPTaskAnimations) | |
+ (SPTask*)task_animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations | |
{ | |
SPTaskCompletionSource *source = [SPTaskCompletionSource new]; | |
[self animateWithDuration:duration delay:delay options:options animations:animations completion:^(BOOL finished) { | |
[source completeWithValue:@(finished)]; | |
}]; | |
return source.task; | |
} | |
@end | |
static UIView *coloredView(UIColor *color, CGPoint position) | |
{ | |
UIView *v = [[UIView alloc] initWithFrame:(CGRect){.origin = position, .size = {20, 20}}]; | |
v.backgroundColor = color; | |
return v; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
There's probably a need for a "meta"-language to describe a multi-step animation on iOS.