BinAnimation

Link to GitHub

Why use

Necessity: As an iOS development engineer, in daily development work, although there is no need to design all kinds of cool animations like game development, simple animation development is still very necessary.

Functionality: on the one hand, animation can improve the user’s visual experience; on the other hand, it can use the transition time of animation to execute the functional code asynchronously in the background to reduce the adverse experience caused by the excessively long execution time of the functional code.

Advantages: In daily animation development, in addition to the animation classification of UIView, CAAnimation is more used as the core animation library. But as anyone who has used CAAnimation knows, it takes several lines of code to create a simple animation. For complex composite animations, the amount of code increases significantly, which is a burden for developers. Learning from the conciseness of the chain syntax of navigation, BinAnimation performs secondary encapsulation on CAAnimation, which simplifies the use of core animation to a large extent.

How to use

The sample project

  • Click BinAnimation to enter, you can download to the local debugging.

example

  • The creation method of BinAnimation is written in CALayer and NSArray categories and can be called directly from CALayer * and NSArray

    * objects.
[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
    founder.toKeyframe.translationY(200).keyTime(1.0).autoreverses(YES);
}];

[self.layerArr bin_addSameAnimation_sync:^(BinAnimationFounder *founder) {
    founder.toKeyframe.scaleX(0.2).scaleY(0.2).keyTime(1.0).autoreverses(YES);
}];
Copy the code
KeyframeAnimation

case 0:
[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
    founder.toKeyframe.translationY(200).keyTime(1.0).autoreverses(YES);
}];
break;
case 1:
[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
    founder.toKeyframe.scaleX(0.2).scaleY(0.2).keyTime(1.0).autoreverses(YES);
}];
break;
case 2:
[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
    founder.toKeyframe.rotationZ(M_PI).keyTime(1.0).autoreverses(YES);
}];
break;
case 3:
[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
    founder.toKeyframe.translationY(200).scaleXYZ(0.2.0.2.1.0).rotationZ(M_PI).keyTime(1.0).autoreverses(YES);
}];
break;
Copy the code
SpringAnimation

case 0:
[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
    founder.springAnimation.mass(1).stiffness(50).damping(2).initialVelocity(10).byValue([NSValue valueWithCGSize:CGSizeMake(0.200)]);
}];
break;
case 1:
[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
    founder.moreSpringAnimation(@"opacity").mass(1).stiffness(50).damping(2).initialVelocity(10).
    toValue(@0);
}];
break;
Copy the code
TransitionAnimation

case 0: {[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
        [self changeColor];
        founder.transition.type(kCATransitionFade).subtype(kCATransitionFromRight);
    }];
}
break;
case 1: {[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
        [self changeColor];
        founder.transition.type(kCATransitionMoveIn).subtype(kCATransitionFromRight);
    }];
}
break;
case 2: {[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
        [self changeColor];
        founder.transition.type(kCATransitionPush).subtype(kCATransitionFromRight);
    }];
}
break;
case 3: {[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
        [self changeColor];
        founder.transition.type(kCATransitionReveal).subtype(kCATransitionFromRight);
    }];
}
break;
Copy the code
MultiAnimation and AnimationGroup
  • MultiAnimation: Add multiple groups of animations on layer, each of which is completely independent;
  • AnimationGroup: Adds a group animation to the layer. This group animation can contain multiple groups of animation. The properties of the group animation may affect the related properties of each animation.

// MultiAnimation
case 0:
[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
    founder.springAnimation.mass(1).stiffness(50).damping(2).initialVelocity(10).byValue([NSValue valueWithCGSize:CGSizeMake(0.200)]);
    founder.toKeyframe.scaleX(0.2).scaleY(0.2).keyTime(1.0).autoreverses(YES);
}];
break;
case 1:
[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
    founder.toKeyframe.translationY(200).keyTime(1.0).autoreverses(YES);
    [founder keyframeAnimation];
    founder.toKeyframe.opacity(0.0).keyTime(1.0).autoreverses(YES);
}];
break;

// AnimationGroup
case 0:
[self.animationlabel.layer removeAllAnimations];
[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
    float settlingDuration = 0;
    founder.springAnimation.mass(1).stiffness(50).damping(2).initialVelocity(10).byValue([NSValue valueWithCGSize:CGSizeMake(0.200)]).getSettlingDuration(&settlingDuration);
    founder.toKeyframe.scaleX(0.2).scaleY(0.2).keyTime(settlingDuration);
    founder.animationGroup.duration(settlingDuration + 1.0).repeatCount(100);
}];
break;
case 1:
[self.animationlabel.layer removeAllAnimations];
[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
    founder.toKeyframe.translationY(200).keyTime(1.0);
    [founder keyframeAnimation];
    founder.toKeyframe.opacity(0.0).keyTime(1.0).autoreverses(YES);
    founder.animationGroup.duration(2.0).repeatCount(100);
}];
break;
Copy the code
Animation_PauseAndResume
  • Supports animation pause and resume

case 0:
[self.animationlabel.layer bin_pause];
break;
case 1:
[self.animationlabel.layer bin_resume];
break;
Copy the code
Animation_CompletionBlock
  • Supports post-animation callbacks

case 0:
[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
    founder.toKeyframe.translationY(200).keyTime(1.0).autoreverses(YES);
}];
break;
case 1: {[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
        founder.toKeyframe.translationY(200).keyTime(1.0).autoreverses(YES);
    } completion:^(BinAnimationInfo *animationInfo) {
        [self changeColor];
    }];
}
break;
Copy the code
Animation_SyncOrAsync
  • Supports synchronous and asynchronous addition of animation
  • The lag is noticeable when adding a lot of layers synchronously, and can cause stalling if called from the main thread. If you add them asynchronously, the improvement is significant.

case 0:
{
    // In the case of synchronous additions, the array of animations added at all layers is returned.
    NSArray *animationArr = [self.layerArr bin_addSameAnimation_sync:^(BinAnimationFounder *founder) {
        founder.toKeyframe.scaleX(0.2).scaleY(0.2).keyTime(1.0).autoreverses(YES);
    }];
    // animationArr: [{@"layer" : layer, @"animationArray" : animationArr}, ...]
    NSLog(@"AnimationArray: %@", animationArr);
}
break;
case 1:
[self.layerArr bin_addSameAnimation_async:^(BinAnimationFounder *founder) {
    founder.toKeyframe.scaleX(0.2).scaleY(0.2).keyTime(1.0).autoreverses(YES);
}];
break;
Copy the code
Animation_OneOrSome
  • Add the same animation to multiple layers or add the same animation to multiple layers
  • The same animation refers to an animation object; The same animation refers to multiple objects, but the objects have the same content.
  • When adding the same animation to a large number of Layer synchronizations, there is a noticeable lag, which can cause stutter if called from the main thread. If you add the same animation, it will be significantly improved.

case 0:
[self.layerArr bin_addOneAnimation_sync:^(BinAnimationFounder *founder) {
    founder.toKeyframe.scaleX(0.2).scaleY(0.2).keyTime(1.0).autoreverses(YES);
}];
break;
case 1:
[self.layerArr bin_addSameAnimation_sync:^(BinAnimationFounder *founder) {
    founder.toKeyframe.scaleX(0.2).scaleY(0.2).keyTime(1.0).autoreverses(YES);
}];
break;
Copy the code
KeyframeAnimation_FromOrToOrBy
  • Supports setting the first frame of the frame animation as well as the fixed and incremental positioning of the frame

case 0:
[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
    founder.fromKeyframe.translationY(100);
    founder.toKeyframe.translationY(200).keyTime(1.0).autoreverses(YES);
    founder.toKeyframe.translationX(200).keyTime(1.0).autoreverses(YES);
}];
break;
case 1:
[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
    founder.toKeyframe.translationY(200).keyTime(1.0).autoreverses(YES);
    founder.toKeyframe.translationX(200).keyTime(1.0).autoreverses(YES);
}];
break;
case 2:
[self.animationlabel.layer bin_addAnimation_sync:^(BinAnimationFounder *founder) {
    founder.toKeyframe.translationY(200).keyTime(1.0).autoreverses(YES);
    founder.byKeyframe.translationX(200).keyTime(1.0).autoreverses(YES);
}];
break;
Copy the code

How to install

  • Install using CocoaPods.

  • Add to your Podfile:

pod 'BinAnimation'
Copy the code
  • Import header files when needed:
#import "BinAnimation.h"
Copy the code

I am who I am

You please say

Do drop me a comment if you have any thoughts