iOS链式动画、Spring动画,TimingFunction扩展

Logo

available

Summary

AXAnimationChain是一个链式动画库,能够用来轻松的建立基于CAAnimation的链式动画。的组合方式有两种,一种是组合,另外一种则是连接,经过以上两种方式建立的动画,既能够同时进行,也能够按时间前后进行,可使用较少的代码建立出丰富复杂的动画效果:git

简单使用:github

_transitionView.spring.centerBy(CGPointMake(0, 100)).easeOut.spring.sizeBy(CGSizeMake(100, 100)).spring.cornerRadiusBy(4).animate();

SimpleSample

高级使用:objective-c

_transitionView.chainAnimator.basic.target(self).complete(@selector(complete:)).property(@"position").toValue([NSValue valueWithCGPoint:CGPointMake(100, self.view.center.y)]).easeInBack.duration(0.5).combineSpring.target(self).complete(@selector(complete:)).property(@"bounds").toValue([NSValue valueWithCGRect:CGRectMake(0, 0, 100, 100)]).duration(0.5).repeatCount(5).autoreverses.combineSpring.target(self).complete(@selector(complete:)).property(@"transform.rotation").toValue(@(M_PI_4)).duration(0.5).repeatCount(3).beginTime(1.0).autoreverses.nextToBasic.property(@"position").toValue([NSValue valueWithCGPoint:self.view.center]).duration(0.5).combineSpring.property(@"bounds").toValue([NSValue valueWithCGRect:CGRectMake(0, 0, 100, 100)]).duration(0.8).nextToBasic.property(@"transform.rotation").toValue(@(M_PI_4)).duration(1.0).completeWithBlock(nil).animate();

看起来比较冗余,可是细读会发现,其实就只有一行代码.spring

sample

连接组合在协议AXAnimatorChainDelegate中进行定义,分别是:nextTo:combineWith:,在使用的过程当中应当予以区分. 安全

AXAnimationChain基于CoreAnimation定义了几种AnimatorAXChainAnimator是基类,预约义了一系列Animate操做,能够连接组合而且控制动画完成的回调并发

AXChainAnimator
  --AXBasicChainAnimator     ==CABasicAnimation
    --AXSpringChainAnimator  ==CASpringAnimation
  --AXKeyframeChainAnimator  ==CAKeyframeAnimation
  --AXTransitionChainAnimator==CATransitionAnimation

Next-To

经过连接的方式处理两个animator被连接animator将会在前者动画(包含组合的动画)完成以后进行动画, 大概的示例以下:框架

[former nextTo:nexter];

Next-To方法的原型以下:ide

- (instancetype)nextTo:(id<AXAnimatorChainDelegate>)animator;

当向former aniamtor发送nextTo:消息以后,返回的是nexter animator做为下次连接或者组合操做的对象,所以AXAnimationChain定义了几种经常使用的操做:动画

/// 连接到Basic动画而且返回连接的Basic动画.
- (AXBasicChainAnimator *)nextToBasic;
/// 连接到Spring动画而且放回连接的Spring动画.
- (AXSpringChainAnimator *)nextToSpring;
/// 连接到Keyframe动画而且放回连接的Keyframe动画.
- (AXKeyframeChainAnimator *)nextToKeyframe;
/// 连接到Transition动画而且返回连接的Transition动画.
- (AXTransitionChainAnimator *)nextToTransition;

在发送消息以后分别返回对应类型的可操做对象.ui

Combine-With

经过组合的方式处理两个animator,被组合的animator将会与前者动画同时进行,完成的时间以时间最长的为准, 示例以下:

[former combineWith:combiner];

Combine-With方法原型以下:

- (instancetype)combineWith:(nonnull AXChainAnimator *)animator;

当向former animator发送combineWith:消息以后,返回的是combiner animator做为下次连接或者组合操做的对象,在AXAnimationChain中,默认一下几种组合方式:

/// 组合到Basic动画而且返回组合的Basic动画.
- (AXBasicChainAnimator *)combineBasic;
/// 组合到Spring动画而且放回组合的Spring动画.
- (AXSpringChainAnimator *)combineSpring;
/// 组合到Keyframe动画而且放回组合的Keyframe动画.
- (AXKeyframeChainAnimator *)combineKeyframe;
/// 组合到Transition动画而且返回组合的Transition动画.
- (AXTransitionChainAnimator *)combineTransition;

一样的,在向某一操做对象animator发送以上消息以后,将会分别返回对应类型的可操做对象.

Relationship

AXAnimationChain中,关系的管理采用的是二叉树的理论. 某一个animator对应的类结构中,包含了指向父节点superAnimator用于表示父animator, 表示此animatorsuperAnimator所连接的animator, 此时,superAnimatorchildAnimator即指向此animator做为一个闭环链将二者的关系锁定起来; 一样的,某一个animator还拥有一个指向兄弟节点NSArray<AXChainAnimator *>结构:combinedAnimators用于管理所组合的animators,而且,被组合的animator的父节点superAnimator则指向当前animator.

- (void)start {
    NSAssert(_animatedView, @"Animation chain cannot be created because animated view is null.");
    AXChainAnimator *superAnimator = _superAnimator;
    AXChainAnimator *superSuperAnimator = _superAnimator;
    while (superAnimator) {
        superAnimator = superAnimator.superAnimator;
        if (superAnimator) {
            superSuperAnimator = superAnimator;
        }
    }
    if (superSuperAnimator) {
        [superSuperAnimator start];
    } else {
        [self _beginAnimating];
        if (!_childAnimator) [self _clear];
    }
}

AXAnimatioChain就是经过这样的关系把全部连接组合animator管理起来的,在完成关系的连接或组合以后,须要向最后一个animator发送-start消息动画才能正常进行. animator在接收到-start消息以后,会逐级遍历superAnimator直至superAnimator.superAnimator==nil, 此时获取到superSuperAnimator, 从superSuperAnimator自祖先往下逐级进行动画,组合的动画会同时进行,连接的动画则按顺序进行.

Features

  • 轻量级解决方案

  • 基于CoreAnimation的封装,安全、高效!

  • 一行代码搞定复杂的动画管理,提升代码维护效

TimingControl

时间曲线,时间曲线用于描述动画随时间进行的速度,AXAnimationChain除了包含系统默认的时间曲线以外,还提供了以下的曲线以呈现更漂亮的动画:

http://ww1.sinaimg.cn/large/d2297bd2gw1fbmrilba19j21c610047c.jpg

AXSpringAnimation

CoreAnimationiOS2.0就为iOS平台提供了核心动画的支持,可是在iOS9.0以前,一直没有Spring动画,要使用Spring动画要么使用第三方动画库,要么使用系统提供的方法:

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay usingSpringWithDamping:(CGFloat)dampingRatio initialSpringVelocity:(CGFloat)velocity options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^ __nullable)(BOOL finished))completion NS_AVAILABLE_IOS(7_0);

可是系统提供的这个方法也是iOS7.0之后才能使用了,而且在控制上并不是那么容易.

AXSpringAnimation是基于阻尼震动运动模型的Spring动画类,可以完美与CASpringAnimation相通用:

SpringSample

动画中,左边正方形使用的是CASpringAnimation类,右边的则使用的是AXSpringAnimation,二者的动画曲线是一致的.

一样地,AXSpringAnimation的API和CASpringAnimation也是一致的:

@interface AXSpringAnimation : CAKeyframeAnimation
/* The mass of the object attached to the end of the spring. Must be greater
 than 0. Defaults to one. */

@property(assign, nonatomic) CGFloat mass;

/* The spring stiffness coefficient. Must be greater than 0.
 * Defaults to 100. */

@property(assign, nonatomic) CGFloat stiffness;

/* The damping coefficient. Must be greater than or equal to 0.
 * Defaults to 10. */

@property(assign, nonatomic) CGFloat damping;

/* The initial velocity of the object attached to the spring. Defaults
 * to zero, which represents an unmoving object. Negative values
 * represent the object moving away from the spring attachment point,
 * positive values represent the object moving towards the spring
 * attachment point. */

@property(assign, nonatomic) CGFloat initialVelocity;

/* Returns the estimated duration required for the spring system to be
 * considered at rest. The duration is evaluated for the current animation
 * parameters. */

@property(readonly, nonatomic) CFTimeInterval settlingDuration;

/* The objects defining the property values being interpolated between.
 * All are optional, and no more than two should be non-nil. The object
 * type should match the type of the property being animated (using the
 * standard rules described in CALayer.h). The supported modes of
 * animation are:
 *
 * - both `fromValue' and `toValue' non-nil. Interpolates between
 * `fromValue' and `toValue'.
 *
 * - `fromValue' and `byValue' non-nil. Interpolates between
 * `fromValue' and `fromValue' plus `byValue'.
 *
 * - `byValue' and `toValue' non-nil. Interpolates between `toValue'
 * minus `byValue' and `toValue'. */

@property(nullable, strong, nonatomic) id fromValue;
@property(nullable, strong, nonatomic) id toValue;
@property(nullable, strong, nonatomic) id byValue;
@end

Convertable

AXAnimationChain框架还提供了将CABasicAnimation无缝转换为CAKeyframeAnimation的功能:

ConvertSample

动画中,左边是CABasicAnimation,右边是CAKeyframeAnimation,二者对应的动画曲线是一致的.

要使用动画转换,请参考:

#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
#import "CAMediaTimingFunction+Extends.h"

@interface CAAnimation (Convertable)
@end

@interface CAKeyframeAnimation (Convertable)
+ (instancetype)animationWithBasic:(CABasicAnimation *)basicAnimation;
+ (instancetype)animationWithBasic:(CABasicAnimation *)basicAnimation usingValuesFunction:(double (^)(double t, double b, double c, double d))valuesFunction;
@end

Requirements

AXAnimationChain 对系统版本支持到iOS8.0,须要使用到的框架:

  • Foundation.framework

  • UIKit.framework

  • QuartzCore.framework

使用的时候最好使用最新版Xcode.

Adding AXAimationChain To Your Project

CocoaPods

CocoaPods) is the recommended way to add AXAimationChain to your project.

  1. Add a pod entry for AXAimationChain to your Podfile pod 'AXAimationChain', '~> 0.1.0'

  2. Install the pod(s) by running pod install.

  3. Include AXAimationChain wherever you need it with #import "AXAimationChain.h".

  4. 若须要单独使用AXSpringAnimation或者Convertable以及TimingControl等特性的话,只须要将podfile里边AXAnimationChain替换为AXAnimationChain/CoreAnimation便可,即:pod 'AXAimationChain/CoreAnimation', '~> 0.1.0'.

Source files

Alternatively you can directly add all the source files to your project.

  1. Download the latest code version) or add the repository as a git submodule to your git-tracked project. 

  2. Open your project in Xcode, then drag and drop the source group onto your project (use the "Product Navigator view"). Make sure to select Copy items when asked if you extracted the code archive outside of your project. 

  3. Include AXAnimationChain wherever you need it with #import "AXAimationChain.h".

  4. 如单独使用AXSpringAnimation或者Convertable以及TimingControl等特性,只须要导入#import "AXCoreAnimation.h"便可.

License

This code is distributed under the terms and conditions of the MIT license

使用

请参考示例工程代码以及API.

不足

此项目在开展的时候比较庞大,基础的核心类已经构建好了,基本目标已经达成,可是还有不少须要完善的地方,后边会逐步完善并发布Release版本.

声明

转载需注明出处:http://devedbox.com/AXAnimationChain/

相关文章
相关标签/搜索