YHAnimationGroup.m 2.53 KB
//
//  YHAnimationGroup.m
//  YHAnimationDemo
//
//  Created by gaoqiang xu on 2/9/15.
//  Copyright (c) 2015 gaoqiang. All rights reserved.
//

#import "YHAnimationGroup.h"
#import "NSObject+YHAnimationGroupInternal.h"

@interface YHAnimationGroup ()

@property (strong, nonatomic) NSMutableSet *remainingAnimations;
@property (strong, nonatomic) NSMapTable *animationsFinished;

@end

@implementation YHAnimationGroup

- (instancetype)init {
    self = [super init];
    if (self) {
        _remainingAnimations = [NSMutableSet set];
        _animationsFinished = [NSMapTable strongToStrongObjectsMapTable];
    }
    return self;
}

- (void)addAnimation:(POPAnimation *)animation {
    animation.completionBlock = ^(POPAnimation *animation, BOOL finished) {
        for (YHAnimationGroup *group in [NSObject yh_animationGroups]) {
            [group removeAnimation:animation finished:finished];
        }
    };
    
    [self.animationsFinished setObject:@(NO) forKey:animation];
    [self.remainingAnimations addObject:animation];
}

- (void)removeAnimation:(POPAnimation *)animation finished:(BOOL)finished {
    if (![self.remainingAnimations containsObject:animation]) {
        return;
    }
    
    [self.animationsFinished setObject:@(finished) forKey:animation];
    [self.remainingAnimations removeObject:animation];
    
    if ([self.remainingAnimations count] < 1) {
        dispatch_async(dispatch_get_main_queue(), ^{
            if (self.completionBlock) {
                self.completionBlock([self isFinished]);
            }
            
            [self.animationsFinished removeAllObjects];
        });
    }
}

#pragma mark - Properties

- (BOOL)isFinished {
    for (POPAnimation *animation in self.animationsFinished) {
        if (![[self.animationsFinished objectForKey:animation] boolValue]) {
            return NO;
        }
    }
    return YES;
}

@end

@implementation NSObject (YHAnimationGroup)

+ (void)pop_animate:(void (^)(void))animations completion:(void (^)(BOOL))completion {
    YHAnimationGroup *group = [[YHAnimationGroup alloc] init];
    [[self yh_animationGroups] addObject:group];
    
    __weak YHAnimationGroup *weakGroup = group;
    group.completionBlock = ^(BOOL finished) {
        YHAnimationGroup *strongGroup = weakGroup;
        [[self yh_animationGroups] removeObject:strongGroup];
        
        if (completion) {
            completion(finished);
        }
    };
    
    [self yh_setActiveAnimationGroup:group];
    
    if (animations) {
        animations();
    }
    
    [self yh_setActiveAnimationGroup:nil];
}

@end