Created
March 13, 2016 13:22
-
-
Save vadimsmirnovnsk/bce345ab81a1cea25a38 to your computer and use it in GitHub Desktop.
Objective-C animation chaining utility
This file contains 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
@interface BARAnimation : NSObject | |
/*! Just start to construct your animation from this method. */ | |
+ (instancetype)construct; | |
/*! Before all animations will execute this block. */ | |
- (instancetype)initially:(void (^)(void))initiallyBlock; | |
/*! Add animations and link it with each other. */ | |
- (instancetype)animationWithDuration:(NSTimeInterval)duration | |
animationConditions:(void (^)(void))conditions | |
animations:(void (^)(void))animations; | |
/*! Add animations with parameters and link it with each other. */ | |
- (instancetype)animationWithDuration:(NSTimeInterval)duration | |
delay:(NSTimeInterval)delay | |
options:(UIViewAnimationOptions)options | |
animationConditions:(void (^)(void))conditions | |
animations:(void (^)(void))animations; | |
/*! After completion all of animation block this block will be called. */ | |
- (instancetype)finally:(void (^)(void))finallyBlock; | |
/*! When you construct your animation, just run it. */ | |
- (void)run; | |
/*! Just syntax sugar for linking animations. You don't need to use it. */ | |
- (instancetype)then; | |
@end |
This file contains 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 "BARAnimation.h" | |
@interface BARAnimationBlock : NSObject | |
@property (nonatomic, copy, readonly) dispatch_block_t conditions; | |
@property (nonatomic, copy, readonly) dispatch_block_t animations; | |
@property (nonatomic, assign, readonly) NSTimeInterval duration; | |
@property (nonatomic, assign, readonly) NSTimeInterval delay; | |
@property (nonatomic, assign, readonly) UIViewAnimationOptions options; | |
- (instancetype)initWithDuration:(NSTimeInterval)duration | |
delay:(NSTimeInterval)delay | |
options:(UIViewAnimationOptions)options | |
animationConditions:(void (^)(void))conditions | |
animations:(void (^)(void))animations; | |
@end | |
@implementation BARAnimationBlock | |
- (instancetype)initWithDuration:(NSTimeInterval)duration | |
delay:(NSTimeInterval)delay | |
options:(UIViewAnimationOptions)options | |
animationConditions:(void (^)(void))conditions | |
animations:(void (^)(void))animations | |
{ | |
self = [super init]; | |
if (self == nil) return nil; | |
_duration = duration; | |
_delay = delay; | |
_options = options; | |
_conditions = [conditions copy]; | |
_animations = [animations copy]; | |
return self; | |
} | |
@end | |
@interface BARAnimation () | |
@property (nonatomic, strong, readonly) NSMutableArray<BARAnimationBlock *> *animationBlocks; | |
@property (nonatomic, copy, readonly) dispatch_block_t finallyBlock; | |
@property (nonatomic, copy, readonly) dispatch_block_t initiallyBlock; | |
@end | |
@implementation BARAnimation | |
+ (instancetype)construct | |
{ | |
return [[BARAnimation alloc] init]; | |
} | |
- (instancetype)init | |
{ | |
self = [super init]; | |
if (self == nil) return nil; | |
_animationBlocks = [NSMutableArray array]; | |
return self; | |
} | |
- (instancetype)animationWithDuration:(NSTimeInterval)duration | |
animationConditions:(void (^)(void))conditions | |
animations:(void (^)(void))animations | |
{ | |
[self.animationBlocks addObject:[[BARAnimationBlock alloc] initWithDuration:duration | |
delay:0.0 | |
options:0 | |
animationConditions:conditions | |
animations:animations]]; | |
return self; | |
} | |
- (instancetype)animationWithDuration:(NSTimeInterval)duration | |
delay:(NSTimeInterval)delay | |
options:(UIViewAnimationOptions)options | |
animationConditions:(void (^)(void))conditions | |
animations:(void (^)(void))animations | |
{ | |
[self.animationBlocks addObject:[[BARAnimationBlock alloc] initWithDuration:duration | |
delay:delay | |
options:options | |
animationConditions:conditions | |
animations:animations]]; | |
return self; | |
} | |
- (instancetype)then | |
{ | |
return self; | |
} | |
- (instancetype)finally:(void (^)(void))finallyBlock | |
{ | |
_finallyBlock = [finallyBlock copy]; | |
return self; | |
} | |
- (instancetype)initially:(void (^)(void))initiallyBlock | |
{ | |
_initiallyBlock = [initiallyBlock copy]; | |
return self; | |
} | |
- (void)run | |
{ | |
if (self.initiallyBlock) | |
{ | |
self.initiallyBlock(); | |
} | |
[self runAnimationWithIndex:0]; | |
} | |
// Recursive call animations | |
- (void)runAnimationWithIndex:(NSUInteger)index | |
{ | |
if (self.animationBlocks.count > index) | |
{ | |
BARAnimationBlock *block = self.animationBlocks[index]; | |
if (block.conditions) | |
{ | |
block.conditions(); | |
} | |
[UIView animateWithDuration:block.duration delay:block.delay options:block.options animations:^{ | |
if (block.animations) | |
{ | |
block.animations(); | |
} | |
} completion:^(BOOL finished) { | |
if (finished) | |
{ | |
[self runAnimationWithIndex:index + 1]; | |
}; | |
}]; | |
} | |
else | |
{ | |
if (self.finallyBlock) | |
{ | |
self.finallyBlock(); | |
} | |
} | |
} | |
@end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Description
Simple class for chaining animations in functional style for iOS.
Why?
For example, look at the chained animations below:
Looks terrible, yeah? Just imagine how will you change this animation for a new product purpose.
And you can rewrite it with
BARAnimation
like that:So, I can add some animations or remove any parts of them any time when I want.
Just hit the star if you like it)
Cheers.