ifish/Ifish/MMProgressHUD/MMProgressHUD+Animations.m

663 lines
24 KiB
Objective-C
Executable File

//
// MMProgressHUD+Animations.m
// MMProgressHUDDemo
//
// Created by Lars Anderson on 7/2/12.
// Copyright (c) 2012 Mutual Mobile. All rights reserved.
//
#import <QuartzCore/QuartzCore.h>
#import "MMProgressHUD+Animations.h"
#import "MMProgressHUDCommon.h"
@interface MMProgressHUD ()
- (CGPoint)_windowCenterForHUDAnchor:(CGPoint)anchor;
@end
@implementation MMProgressHUD (Animations)
@dynamic queuedShowAnimation;
@dynamic queuedDismissAnimation;
@dynamic visible;
#pragma mark - Animations
- (CAAnimationGroup *)_glowAnimation {
CABasicAnimation *glowAnimation = [CABasicAnimation animationWithKeyPath:@"shadowColor"];
glowAnimation.fromValue = (id)self.hud.layer.shadowColor;
glowAnimation.toValue = (id)self.glowColor;
CABasicAnimation *shadowOpacity = [CABasicAnimation animationWithKeyPath:@"shadowOpacity"];
shadowOpacity.fromValue = @(self.hud.layer.shadowOpacity);
shadowOpacity.toValue = @1.f;
CGColorRef whiteishColor = CGColorRetain([UIColor colorWithWhite:0.f alpha:0.85f].CGColor);
CABasicAnimation *hudBackground = [CABasicAnimation animationWithKeyPath:@"backgroundColor"];
hudBackground.fromValue = (id)self.hud.layer.backgroundColor;
hudBackground.toValue = (__bridge id)whiteishColor;
CGColorRelease(whiteishColor);
CAAnimationGroup *glowGroup = [CAAnimationGroup animation];
glowGroup.animations = @[glowAnimation, shadowOpacity, hudBackground];
glowGroup.duration = MMProgressHUDAnimateInDurationNormal;
glowGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
glowGroup.autoreverses = YES;
glowGroup.repeatCount = INFINITY;
return glowGroup;
}
- (void)_beginGlowAnimation {
CAAnimationGroup *glowGroup = [self _glowAnimation];
[self.hud.layer addAnimation:glowGroup forKey:@"glow-animation"];
}
- (void)_endGlowAnimation {
[self.hud.layer removeAnimationForKey:@"glow-animation"];
}
- (void)_showWithDropAnimation {
self.hud.layer.anchorPoint = CGPointMake(0.5f, 0.f);
CGPoint newCenter = [self _windowCenterForHUDAnchor:self.hud.layer.anchorPoint];
[CATransaction begin];
[CATransaction setDisableActions:YES];
{
self.hud.center = CGPointMake(newCenter.x, -CGRectGetHeight(self.hud.frame));
self.hud.layer.opacity = 1.f;
[self _executeShowAnimation:[self _dropAnimationIn]];
}
[CATransaction commit];
}
- (void)_dismissWithDropAnimation {
double newAngle = arc4random_uniform(1000)/1000.f*M_2_PI-(M_2_PI)/2.f;
CGPoint newPosition = CGPointMake(self.hud.layer.position.x, self.frame.size.height + self.hud.frame.size.height);
[CATransaction begin];
[CATransaction setDisableActions:YES];
{
[self _executeDismissAnimation:[self _dropAnimationOut]];
// Don't shift the position if we're in a queue...
if ([self.hud.layer animationForKey:MMProgressHUDAnimationKeyShowAnimation] == nil) {
self.hud.layer.position = newPosition;
self.hud.layer.transform = CATransform3DMakeRotation(newAngle, 0.f, 0.f, 1.f);
}
}
[CATransaction commit];
}
- (void)_showWithExpandAnimation {
self.hud.layer.anchorPoint = CGPointMake(0.5, 0.5);
self.hud.layer.position = [self _windowCenterForHUDAnchor:self.hud.layer.anchorPoint];
self.hud.alpha = 0.f;
[CATransaction begin];
[CATransaction setDisableActions:YES];
{
self.hud.layer.transform = CATransform3DIdentity;
self.hud.layer.opacity = 1.0f;
[self _executeShowAnimation:[self _shrinkAnimation:NO animateOut:NO]];
}
[CATransaction commit];
}
- (void)_dismissWithExpandAnimation {
[CATransaction begin];
[CATransaction setDisableActions:YES];
{
self.hud.layer.transform = CATransform3DMakeScale(3.f, 3.f, 1.f);
self.hud.layer.opacity = 0.f;
[self _executeDismissAnimation:[self _shrinkAnimation:NO animateOut:YES]];
}
[CATransaction commit];
}
- (void)_showWithShrinkAnimation {
self.hud.layer.anchorPoint = CGPointMake(0.5, 0.5);
self.hud.layer.position = [self _windowCenterForHUDAnchor:self.hud.layer.anchorPoint];
self.hud.alpha = 0.f;
[CATransaction begin];
[CATransaction setDisableActions:YES];
{
self.hud.layer.transform = CATransform3DIdentity;
self.hud.layer.opacity = 1.0f;
[self _executeShowAnimation:[self _shrinkAnimation:YES animateOut:NO]];
}
[CATransaction commit];
}
- (void)_dismissWithShrinkAnimation {
[CATransaction begin];
[CATransaction setDisableActions:YES];
{
self.hud.layer.transform = CATransform3DMakeScale(0.25, 0.25, 1.f);
self.hud.layer.opacity = 0.f;
[self _executeDismissAnimation:[self _shrinkAnimation:YES animateOut:YES]];
}
[CATransaction commit];
}
- (void)_showWithSwingInAnimationFromLeft:(BOOL)fromLeft NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extensions."){
self.hud.layer.anchorPoint = CGPointMake(0.5f, 0.0f);
[CATransaction begin];
[CATransaction setDisableActions:YES];
{
self.hud.layer.opacity = 1.f;
self.hud.layer.position = [self _windowCenterForHUDAnchor:self.hud.layer.anchorPoint];
[self _executeShowAnimation:[self _swingInAnimationFromLeft:fromLeft]];
}
[CATransaction commit];
}
- (void)_dismissWithSwingRightAnimation {
[self _dismissWithDropAnimation];
}
- (void)_dismissWithSwingLeftAnimation {
[self _dismissWithDropAnimation];
}
- (void)_showWithBalloonAnimation {
self.hud.layer.anchorPoint = CGPointMake(0.5, 1.0);
[CATransaction begin];
[CATransaction setDisableActions:YES];
{
self.hud.layer.opacity = 1.f;
CGPoint center = [self _windowCenterForHUDAnchor:self.hud.layer.anchorPoint];
self.hud.layer.position = CGPointMake(center.x, CGRectGetHeight(self.frame) + CGRectGetHeight(self.hud.frame));
// self.hud.layer.position = center;
[self _executeShowAnimation:[self _balloonAnimationIn]];
}
[CATransaction commit];
}
- (void)_dismissWithBalloonAnimation {
self.hud.layer.anchorPoint = CGPointMake(0.5f, 1.0f);
[CATransaction begin];
[CATransaction setDisableActions:YES];
{
self.hud.layer.transform = CATransform3DMakeRotation(M_PI_2, 0.f, 0.f, 1.f);
[self _executeDismissAnimation:[self _balloonAnimationOut]];
CGPoint center = [self _windowCenterForHUDAnchor:self.hud.layer.anchorPoint];
self.hud.layer.position = CGPointMake(center.x, -CGRectGetHeight(self.hud.frame));
}
[CATransaction commit];
}
- (void)_showWithFadeAnimation {
self.hud.layer.anchorPoint = CGPointMake(0.5, 0.5);
self.hud.layer.transform = CATransform3DIdentity;
[CATransaction begin];
[CATransaction setDisableActions:YES];
{
[self _executeShowAnimation:[self _fadeInAnimation]];
self.hud.layer.opacity = 1.f;
self.hud.layer.position = [self _windowCenterForHUDAnchor:self.hud.layer.anchorPoint];
}
[CATransaction commit];
}
- (void)_dismissWithFadeAnimation {
self.hud.layer.anchorPoint = CGPointMake(0.5, 0.5);
self.hud.layer.transform = CATransform3DIdentity;
[CATransaction begin];
[CATransaction setDisableActions:YES];
{
[self _executeDismissAnimation:[self _fadeOutAnimation]];
self.hud.layer.opacity = 0.f;
self.hud.layer.position = [self _windowCenterForHUDAnchor:self.hud.layer.anchorPoint];
}
[CATransaction commit];
}
#pragma mark - Animation Foundries
- (CAKeyframeAnimation *)_dropInAnimationPositionAnimationWithCenter:(CGPoint)newCenter {
CAKeyframeAnimation *dropInPositionAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, self.hud.center.x, self.hud.center.y);
CGPathAddLineToPoint(path, NULL, newCenter.x - 10.f, newCenter.y - 2.f);
CGPathAddCurveToPoint(path, NULL,
newCenter.x, newCenter.y - 10.f,
newCenter.x + 10.f, newCenter.y - 10.f,
newCenter.x + 5.f, newCenter.y - 2.f);
CGPathAddCurveToPoint(path, NULL,
newCenter.x + 7, newCenter.y - 7.f,
newCenter.x, newCenter.y - 7.f,
newCenter.x - 3.f, newCenter.y);
CGPathAddCurveToPoint(path, NULL,
newCenter.x, newCenter.y - 4.f,
newCenter.x , newCenter.y - 4.f,
newCenter.x, newCenter.y);
dropInPositionAnimation.path = path;
dropInPositionAnimation.calculationMode = kCAAnimationCubic;
dropInPositionAnimation.keyTimes = @[@0.0f,
@0.25f,
@0.35f,
@0.55f,
@0.7f,
@1.0f];
dropInPositionAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
CGPathRelease(path);
return dropInPositionAnimation;
}
- (CAKeyframeAnimation *)_dropInAnimationRotationAnimationWithInitialAngle:(CGFloat)initialAngle keyTimes:(NSArray *)keyTimes {
CAKeyframeAnimation *rotation = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation.z"];
rotation.values = @[@(initialAngle),
@(-initialAngle * 0.85),
@(initialAngle * 0.6),
@(-initialAngle * 0.3),
@0.f];
rotation.calculationMode = kCAAnimationCubic;
rotation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
rotation.keyTimes = keyTimes;
return rotation;
}
- (CAAnimation *)_dropAnimationIn {
CGFloat initialAngle = M_2_PI/10.f + arc4random_uniform(1000)/1000.f*M_2_PI/5.f;
CGPoint newCenter = [self _windowCenterForHUDAnchor:self.hud.layer.anchorPoint];
MMHudLog(@"Center after drop animation: %@", NSStringFromCGPoint(newCenter));
CAKeyframeAnimation *dropInAnimation = [self _dropInAnimationPositionAnimationWithCenter:newCenter];
CAKeyframeAnimation *rotationAnimation = [self _dropInAnimationRotationAnimationWithInitialAngle:initialAngle
keyTimes:dropInAnimation.keyTimes];
CAAnimationGroup *showAnimation = [CAAnimationGroup animation];
showAnimation.animations = @[dropInAnimation, rotationAnimation];
showAnimation.duration = MMProgressHUDAnimateInDurationLong;
[self _executeShowAnimation:showAnimation];
self.hud.layer.position = newCenter;
self.hud.layer.transform = CATransform3DIdentity;
return showAnimation;
}
- (CAAnimation *)_dropAnimationOut {
double newAngle = arc4random_uniform(1000)/1000.f*M_2_PI-(M_2_PI)/2.f;
CATransform3D rotation = CATransform3DMakeRotation(newAngle, 0.f, 0.f, 1.f);
CGPoint newPosition = CGPointMake(self.hud.layer.position.x, self.frame.size.height + self.hud.frame.size.height);
CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
rotationAnimation.fromValue = [NSValue valueWithCATransform3D:self.hud.layer.transform];
rotationAnimation.toValue = [NSValue valueWithCATransform3D:rotation];
CABasicAnimation *positionAnimation = [CABasicAnimation animationWithKeyPath:@"position"];
positionAnimation.fromValue = [NSValue valueWithCGPoint:self.hud.layer.position];
positionAnimation.toValue = [NSValue valueWithCGPoint:newPosition];
CAAnimationGroup *fallOffAnimation = [CAAnimationGroup animation];
fallOffAnimation.animations = @[rotationAnimation, positionAnimation];
fallOffAnimation.duration = MMProgressHUDAnimateOutDurationLong;
fallOffAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
fallOffAnimation.removedOnCompletion = YES;
return fallOffAnimation;
}
- (CAAnimation *)_shrinkAnimation:(BOOL)shrink animateOut:(BOOL)fadeOut {
CGFloat startingOpacity;// = fadeOut ? 1.0 : 0.f;
CGFloat startingScale;// = shrink ? 0.25 : 1.0f;
CGFloat endingOpacity;
CGFloat endingScale;
if (fadeOut) { //shrink & expand out
startingOpacity = 1.f;
startingScale = 1.f;
endingOpacity = 0.f;
if (shrink) {
endingScale = 0.25f;
}
else {
endingScale = 3.f;
}
}
else {
startingOpacity = 0.f;
endingScale = 1.f;
endingOpacity = 1.f;
if (shrink) {//shrink in
startingScale = 3.f;
}
else {//expand in
startingScale = 0.25f;
}
}
CAKeyframeAnimation *expand = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
if (fadeOut) {
expand.keyTimes = @[@0.f,
@0.45f,
@1.0f];
if (shrink) {
expand.values = @[@(startingScale),
@(startingScale*1.2f),
@(endingScale)];
}
else {
expand.values = @[@(startingScale),
@(startingScale*0.8f),
@(endingScale)];
}
}
else {
expand.keyTimes = @[@0.f,
@0.65f,
@0.80f,
@1.0f];
if (shrink) {
expand.values = @[@(startingScale),
@(endingScale*0.9f),
@(endingScale*1.1f),
@(endingScale)];
}
else {
expand.values = @[@(startingScale),
@(endingScale*1.1f),
@(endingScale*0.9f),
@(endingScale)];
}
}
expand.calculationMode = kCAAnimationCubic;
CABasicAnimation *fade = [CABasicAnimation animationWithKeyPath:@"opacity"];
fade.fromValue = @(startingOpacity);
fade.toValue = @(endingOpacity);
fade.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.animations = @[expand, fade];
animationGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
animationGroup.duration = fadeOut ? MMProgressHUDAnimateOutDurationShort : MMProgressHUDAnimateInDurationShort;
return animationGroup;
}
- (CAAnimation *)_swingInAnimationFromLeft:(BOOL)fromLeft NS_EXTENSION_UNAVAILABLE_IOS("Not available in app extensions."){
CAKeyframeAnimation *rotate = [CAKeyframeAnimation animationWithKeyPath:@"transform.rotation"];
CGPoint endPoint = [self _windowCenterForHUDAnchor:self.hud.layer.anchorPoint];
CGPoint startPoint;
CGFloat height;
CGFloat width;
CGMutablePathRef path = CGPathCreateMutable();
CGPoint cp1;
CGPoint cp2;
if (UIInterfaceOrientationIsPortrait([[[[UIApplication sharedApplication] keyWindow] rootViewController] interfaceOrientation])) {
height = CGRectGetHeight(self.window.frame);
width = CGRectGetWidth(self.window.frame);
}
else {
height = CGRectGetWidth(self.window.frame);
width = CGRectGetHeight(self.window.frame);
}
if (fromLeft) { //swing in from left
startPoint = CGPointMake(-CGRectGetWidth(self.hud.frame), 0.f);
cp1 = CGPointMake(startPoint.x + 10.f, startPoint.y + height/4);
cp2 = CGPointMake(endPoint.x - width/4, endPoint.y);
rotate.values = @[[NSNumber numberWithFloat:M_PI_4],
@0.0f,
[NSNumber numberWithFloat:-M_PI_4/6],
[NSNumber numberWithFloat:M_PI_4/12],
@0.0f];
}
else {//swing in from right
if (UIInterfaceOrientationIsPortrait([[[[UIApplication sharedApplication] keyWindow] rootViewController] interfaceOrientation])) {
startPoint = CGPointMake(CGRectGetWidth(self.window.frame) + CGRectGetWidth(self.hud.frame), 0.f);
}
else {
startPoint = CGPointMake(CGRectGetHeight(self.window.frame) + CGRectGetWidth(self.hud.frame), 0.f);
}
cp1 = CGPointMake(startPoint.x - 10.f, startPoint.y + height/4);
cp2 = CGPointMake(endPoint.x + width/4, endPoint.y);
rotate.values = @[[NSNumber numberWithFloat:-M_PI_4],
@0.0f,
[NSNumber numberWithFloat:M_PI_4/6],
[NSNumber numberWithFloat:-M_PI_4/12],
@0.0f];
}
MMHudLog(@"Start point: %@", NSStringFromCGPoint(startPoint));
MMHudLog(@"End Point: %@", NSStringFromCGPoint(endPoint));
MMHudLog(@"cp1: %@", NSStringFromCGPoint(cp1));
MMHudLog(@"cp2: %@", NSStringFromCGPoint(cp2));
CGPathMoveToPoint(path, NULL, startPoint.x, startPoint.y);
CGPathAddCurveToPoint(path, NULL, cp1.x, cp1.y, cp2.x, cp2.y, endPoint.x, endPoint.y);
CGPathAddLineToPoint(path, NULL, endPoint.x - 5.f, endPoint.y);
CGPathAddLineToPoint(path, NULL, endPoint.x + 3.f, endPoint.y);
CGPathAddLineToPoint(path, NULL, endPoint.x, endPoint.y);
CAKeyframeAnimation *swing = [CAKeyframeAnimation animationWithKeyPath:@"position"];
swing.path = path;
swing.calculationMode = kCAAnimationCubic;
swing.keyTimes = @[@0.0f,
@0.75f,
@0.8f,
@0.9f,
@1.0f];
swing.timingFunctions = @[[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];
CGPathRelease(path);
rotate.keyTimes = swing.keyTimes;
rotate.timingFunctions = swing.timingFunctions;
rotate.calculationMode = kCAAnimationCubic;
CAAnimationGroup *group = [CAAnimationGroup animation];
group.animations = @[swing, rotate];
group.duration = MMProgressHUDAnimateInDurationMedium;
return group;
}
- (CAAnimation *)_moveInAnimation {
CATransition *transition = [CATransition animation];
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromRight;
transition.duration = 0.33f;
return transition;
}
- (CAAnimation *)_fadeInAnimation {
NSString *opacityKey = @"opacity";
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:opacityKey];
NSNumber *currentValue = [self.hud.layer valueForKey:opacityKey];
if ([currentValue floatValue] == 1.f) {
animation.fromValue = @(0.f);
}
else {
animation.fromValue = [self.hud.layer.presentationLayer valueForKey:opacityKey];;
}
animation.toValue = @(1.f);
animation.duration = MMProgressHUDAnimateInDurationShort;
return animation;
}
- (CAAnimation *)_fadeOutAnimation {
NSString *opacityKey = @"opacity";
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:opacityKey];
animation.fromValue = [self.hud.layer.presentationLayer valueForKey:opacityKey];
animation.toValue = @(0.f);
animation.duration = MMProgressHUDAnimateOutDurationMedium;
return animation;
}
- (CAAnimation *)_balloonAnimationIn {
return [self _dropAnimationIn];
}
- (CAAnimation *)_balloonAnimationOut {
CGPoint newPosition = CGPointMake(self.hud.layer.position.x, -self.hud.frame.size.height);
CAKeyframeAnimation *positionAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
positionAnimation.calculationMode = kCAAnimationCubic;
CGPoint currentPosition = self.hud.layer.position;
CGPoint travelVector = CGPointMake(newPosition.x - currentPosition.x, newPosition.y - currentPosition.y);
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, self.hud.layer.position.x, self.hud.layer.position.y);
CGPathAddCurveToPoint(path, NULL,
currentPosition.x, currentPosition.y + travelVector.y/4,
newPosition.x - 50.f, newPosition.y - travelVector.y/2,
newPosition.x, newPosition.y);
positionAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
positionAnimation.rotationMode = kCAAnimationRotateAuto;
positionAnimation.path = path;
positionAnimation.duration = MMProgressHUDAnimateOutDurationLong;
positionAnimation.removedOnCompletion = YES;
CGPathRelease(path);
return positionAnimation;
}
- (CAAnimation *)_confettiAnimationOut {
// self.hud.layer dr
return nil;
}
#pragma mark - Execution
- (void)_executeShowAnimation:(CAAnimation *)animation {
[animation setValue:MMProgressHUDAnimationShow forKey:@"name"];
self.visible = YES;
__typeof(self) __weak weakSelf = self;
void(^showCompletion)(void) = ^(void) {
MMProgressHUD *blockSelf = weakSelf;
MMHudLog(@"Show animation ended: %@", blockSelf.hud);
self.visible = YES;
blockSelf.queuedShowAnimation = nil;
if (blockSelf.showAnimationCompletion != nil) {
blockSelf.showAnimationCompletion();
blockSelf.showAnimationCompletion = nil;
}
if (blockSelf.queuedDismissAnimation != nil) {
[blockSelf _executeDismissAnimation:blockSelf.queuedDismissAnimation];
blockSelf.queuedDismissAnimation = nil;
}
};
if ([self.hud.layer animationForKey:MMProgressHUDAnimationKeyDismissAnimation] != nil) {
self.queuedShowAnimation = animation;
}
else if ([self.hud.layer animationForKey:MMProgressHUDAnimationKeyShowAnimation] == nil) {
self.queuedShowAnimation = nil;
[CATransaction begin];
[CATransaction setCompletionBlock:showCompletion];
{
[self.hud.layer addAnimation:animation forKey:MMProgressHUDAnimationKeyShowAnimation];
}
[CATransaction commit];
}
}
- (void)_executeDismissAnimation:(CAAnimation *)animation {
[animation setValue:MMProgressHUDAnimationDismiss forKey:@"name"];
self.visible = NO;
__typeof(self) __weak weakSelf = self;
void(^endCompletion)(void) = ^(void) {
MMProgressHUD *blockSelf = weakSelf;
MMHudLog(@"Dismiss animation ended");
self.visible = NO;
if (blockSelf.dismissAnimationCompletion != nil) {
blockSelf.dismissAnimationCompletion();
blockSelf.dismissAnimationCompletion = nil;
}
[blockSelf.hud removeFromSuperview];
blockSelf.queuedDismissAnimation = nil;
//reset for next presentation
[blockSelf.hud prepareForReuse];
if (blockSelf.queuedShowAnimation != nil) {
[blockSelf _executeShowAnimation:blockSelf.queuedShowAnimation];
}
};
if ([self.hud.layer animationForKey:MMProgressHUDAnimationKeyShowAnimation] != nil) {
self.queuedDismissAnimation = animation;
}
else if ([self.hud.layer animationForKey:MMProgressHUDAnimationKeyDismissAnimation] == nil) {
self.queuedDismissAnimation = nil;
[CATransaction begin];
[CATransaction setCompletionBlock:endCompletion];
{
[self.hud.layer addAnimation:animation forKey:MMProgressHUDAnimationKeyDismissAnimation];
}
[CATransaction commit];
}
}
@end