此项目受 JHChainableAnimations 启发!
为什么选择 LSAnimator 和 CoreAnimator?
通过使用 LSAnimator (Objective-C) 或 CoreAnimator (Swift),您只需几行代码就可以编写复杂且易于维护的动画。
什么是多链动画?
CAAnimations和UIView动画功能非常强大,但动画复杂时阅读起来非常困难。
例如,我想使用弹簧移动myView 100像素到右侧,当移动完成时,再用内缩减速(inward easing)增加30像素的宽度
老方法
[UIView animateWithDuration:2.0
delay:0.0
usingSpringWithDamping:0.8
initialSpringVelocity:1.0
options:0
animations:^{
CGPoint newPosition = self.myView.frame.origin;
newPosition.x += 100;
self.myView.frame = CGRectMake(newPosition.x, newPosition.y, self.myView.frame.size.width, self.myView.frame.size.height);
} completion:^(BOOL finished) {
[UIView animateWithDuration:2.0
delay:0.0
options:UIViewAnimationOptionCurveEaseIn
animations:^{
CGSize newSize = self.myView.frame.size;
newSize.width += 30;
self.myView.frame = CGRectMake(self.myView.frame.origin.x, self.myView.frame.origin.y, newSize.width, newSize.height);
} completion:nil];
}];
这有点糟糕,不是吗?使用LSAnimator只需一行代码。
使用LSAnimator
LSAnimator *animator = [LSAnimator animatorWithView:self.myView];
animator.moveX(100).spring.thenAfter(2).increWidth(30).easeIn.animate(2);
呃……还有一个名为JHChainableAnimations的动画库也可以做到这一点。
JHChainableAnimations的不足之处?
JHChainableAnimations具有强大的可链式动画和易于读写语法,但支持多链动画。
按照上面的示例,假设现在整个动画链需要同时将myView的透明度改为零。
使用LSAnimator
使用LSAnimator只需添加一行代码即可。
LSAnimator *animator = [LSAnimator animatorWithView:self.myView];
animator.moveX(100).spring.thenAfter(2).increWidth(30).easeIn.animate(2);
animator.concurrent.makeOpacity(0).animate(4);
使用 JHChainableAnimations
呃,使用 JHChainableAnimations 无法完成任务。尝试添加以下代码将导致动画错误或崩溃。
JHChainableAnimator *animator = [[JHChainableAnimator alloc] initWithView:self.myView];
animator.moveX(100).spring.thenAfter(2).moveWidth(30).easeIn.animate(2);
animator.makeOpacity(0).animate(4);
LSAnimator 与 JHChainableAnimations
- 多链动画:可以满足所有动画设计需求,比 JHChainableAnimations 更灵活。
- CALayer 支持:支持 CALayer 初始化,JHChainableAnimations 只支持 UIView。
- 参数自动完成:支持参数自动完成,JHChainableAnimations 不支持。
LSAnimator 支持参数自动完成,包括参数数量和参数类型。
JHChainableAnimations 在实际编写代码时不够友好。
JHChainableAnimations 仍然是一个非常优秀的动画库,LSAnimator 是站在它的肩膀上的。
特点
- Swift 支持:支持 Swift 3.2 ~ 4。
- 友好的 Swift 接口:在单独的框架中添加了友好的 Swift 接口。
- 多链动画:可以满足所有动画设计需求。
- CALayer 支持:支持 CALayer 初始化。
- 参数自动完成:支持参数自动完成。
- 支持动画钩子:为每个动画步骤添加了预动画和后动画钩子。添加了一个最终完成钩子,当所有动画链都完成后触发。
- 非侵入性:无需将视图/层类从其他基类继承。
使用
创建动画器
// UIView initialization
LSAnimator *viewAnimator = [LSAnimator animatorWithView:self.myView];
LSAnimator *viewAnimator = [[LSAnimator alloc] initWithView:self.myView];
// CALayer initialization
LSAnimator *layerAnimator = [LSAnimator animatorWithLayer:self.myLayer];
LSAnimator *layerAnimator = [[LSAnimator alloc] initWithLayer:self.myLayer];
动画
如 moveX(x)
之类的可链式属性必须放在动画和 animate(t)
函数之间。
以下是一个在1秒内将对象大小加倍示例。
animator.makeScale(2.0).animate(1.0);
组合动画
如果你想在缩放视图的同时移动视图,添加另一个可链式属性。顺序不明显。
animator.makeScale(2.0).moveXY(100, 50).animate(1.0);
// the same as animator.moveXY(100, 50).makeScale(2.0).animate(1.0);
注意:组合动画仅适用于需要同时步骤完成的动画。
如果动画有不同的持续时间。当它们 不能在同一动画步骤中完成,它们需要使用 多链式动画。
可链式属性的完整列表可以在 这里 找到。
链式动画
要通过 thenAfter(t)
函数分隔动画链,从而串联动画。
以下是如何在0.5秒内缩放对象,然后在该动作完成后移动对象的示例。
animator.makeScale(2.0).thenAfter(0.5).moveXY(100, 50).animate(1.0);
动画效果
要在动画中添加动画效果,请在该效果应应用的可链式属性之后调用效果方法。
以下是如何使用弹簧效果缩放视图的示例。
animator.makeScale(2.0).spring.animate(1.0);
如果你向同一可链式属性添加2,则第二个将取消第一个。
animator.makeScale(2.0).bounce.spring.animate(1.0);
// The same as animator.makeScale(2.0).spring.animate(1.0);
动画效果属性的完整列表可以在 这里 找到。
锚定
要在动画链中的某一点调用锚定方法来锚定视图。类似于效果,在相同链中依次调用将取消第一个效果。
下面是一个绕不同锚点旋转视图的示例。
animator.rotateZ(180).anchorTopLeft.thenAfter(1.0).rotateZ(90).anchorCenter.animate(1.0);
// animator.rotateZ(90).anchorTopLeft.anchorCenter == animator.rotateZ(90).anchorCenter
所有锚定属性的完整列表可以在这里找到。
延迟
要延迟动画,请调用wait(t)
或delay(t)
链式属性。
下面是一个在0.5秒延迟后移动视图的示例。
animator.moveXY(100, 50).wait(0.5).animate(1.0);
// The same as animator.moveXY(100, 50).delay(0.5).animate(1.0);
完成
在动画完成后运行代码,请调用animateWithCompletion(t, completion)
函数。
animator.makeX(0).animateWithCompletion(1.0, ^{
NSLog(@"Animation Done");
});
重复动画
您可以通过将thenAfter(time)
方法替换为repeat(time, count)
方法来重复动画。这将重复先前定义的动画。
animator.increWidth(30).spring.repeat(0.5, 3).moveXY(100, 50).animate(1.0);
您还可以通过调用animateWithRepeat(time, count)
来重复动画的最后部分。
animator.increWidth(30).spring.animateWithRepeat(0.5, 3);
回调
您可以通过调用preAnimationBlock(block)
和postAnimationBlock(block)
方法来挂钩动画过程的各个步骤。所有方法均接受一个简单的代码块参数void(^block)(void)
。在动画链中调用这些方法的顺序无关紧要。
animator.moveX(10).preAnimationBlock(^{
NSLog(@"before the first animation");
}).thenAfter(1.0).postAnimationBlock(^{
NSLog(@"After the second animation");
}).moveY(10).animate(1.0);
贝塞尔路径
您还可以将视图沿UIBezierPath动画。创建一个UIBezierPath *
实例,然后向其中添加点或曲线或直线,并在链式属性中使用它。
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:self.myView.center];
[path addLineToPoint:CGPointMake(25, 400)];
[path addLineToPoint:CGPointMake(300, 500)];
animator.moveOnPath(path).animate(1.0);
使用自动布局
变换
使用可链式属性。这更适合受自动布局约束的视图。您不应与其他可链式属性混合使用。
animatorForViewWithConstraints.transformX(50).transformScale(2).animate(1.0);
使用Swift
在2.x版本的Swift中使用LSAnimator
现在会更加容易阅读。我创建了单独的swift框架,提供了名为CoreAnimator
的类。这是一个薄的包装器,基于LSAnimator
,具有更易读的语法。
let animator = CoreAnimator(view: myView)
animator.move(x: 60).thenAfter(t: 1.0).rotate(angle: 360).bounce.animate(t: 1.0)
可链式属性
#pragma mark - Animations
// Makes
// Affects views position and bounds
@property (nonatomic, copy, readonly) LSAnimatorRect makeFrame;
@property (nonatomic, copy, readonly) LSAnimatorRect makeBounds;
@property (nonatomic, copy, readonly) LSAnimatorSize makeSize;
@property (nonatomic, copy, readonly) LSAnimatorPoint makeOrigin;
@property (nonatomic, copy, readonly) LSAnimatorPoint makePosition;
@property (nonatomic, copy, readonly) LSAnimatorFloat makeX;
@property (nonatomic, copy, readonly) LSAnimatorFloat makeY;
@property (nonatomic, copy, readonly) LSAnimatorFloat makeWidth;
@property (nonatomic, copy, readonly) LSAnimatorFloat makeHeight;
@property (nonatomic, copy, readonly) LSAnimatorFloat makeOpacity;
@property (nonatomic, copy, readonly) LSAnimatorColor makeBackground;
@property (nonatomic, copy, readonly) LSAnimatorColor makeBorderColor;
@property (nonatomic, copy, readonly) LSAnimatorFloat makeBorderWidth;
@property (nonatomic, copy, readonly) LSAnimatorFloat makeCornerRadius;
@property (nonatomic, copy, readonly) LSAnimatorFloat makeScale;
@property (nonatomic, copy, readonly) LSAnimatorFloat makeScaleX;
@property (nonatomic, copy, readonly) LSAnimatorFloat makeScaleY;
@property (nonatomic, copy, readonly) LSAnimatorPoint makeAnchor;
// Moves
// Affects views position and bounds
@property (nonatomic, copy, readonly) LSAnimatorFloat moveX;
@property (nonatomic, copy, readonly) LSAnimatorFloat moveY;
@property (nonatomic, copy, readonly) LSAnimatorPoint moveXY;
@property (nonatomic, copy, readonly) LSAnimatorPolarCoordinate movePolar;
// Increments
// Affects views position and bounds
@property (nonatomic, copy, readonly) LSAnimatorFloat increWidth;
@property (nonatomic, copy, readonly) LSAnimatorFloat increHeight;
@property (nonatomic, copy, readonly) LSAnimatorSize increSize;
// Transforms
// Affects views transform property NOT position and bounds
// These should be used for AutoLayout
// These should NOT be mixed with properties that affect position and bounds
- (LSAnimator *)transformIdentity;
@property (nonatomic, copy, readonly) LSAnimatorDegrees rotate; // Same as rotateZ
@property (nonatomic, copy, readonly) LSAnimatorDegrees rotateX;
@property (nonatomic, copy, readonly) LSAnimatorDegrees rotateY;
@property (nonatomic, copy, readonly) LSAnimatorDegrees rotateZ;
@property (nonatomic, copy, readonly) LSAnimatorFloat transformX;
@property (nonatomic, copy, readonly) LSAnimatorFloat transformY;
@property (nonatomic, copy, readonly) LSAnimatorFloat transformZ;
@property (nonatomic, copy, readonly) LSAnimatorPoint transformXY;
@property (nonatomic, copy, readonly) LSAnimatorFloat transformScale; // x and y equal
@property (nonatomic, copy, readonly) LSAnimatorFloat transformScaleX;
@property (nonatomic, copy, readonly) LSAnimatorFloat transformScaleY;
#pragma mark - Bezier Paths
// Animation effects dont apply
@property (nonatomic, copy, readonly) LSAnimatorBezierPath moveOnPath;
@property (nonatomic, copy, readonly) LSAnimatorBezierPath moveAndRotateOnPath;
@property (nonatomic, copy, readonly) LSAnimatorBezierPath moveAndReverseRotateOnPath;
动画效果
- (LSAnimator *)easeIn;
- (LSAnimator *)easeOut;
- (LSAnimator *)easeInOut;
- (LSAnimator *)easeBack;
- (LSAnimator *)spring;
- (LSAnimator *)bounce;
- (LSAnimator *)easeInQuad;
- (LSAnimator *)easeOutQuad;
- (LSAnimator *)easeInOutQuad;
- (LSAnimator *)easeInCubic;
- (LSAnimator *)easeOutCubic;
- (LSAnimator *)easeInOutCubic;
- (LSAnimator *)easeInQuart;
- (LSAnimator *)easeOutQuart;
- (LSAnimator *)easeInOutQuart;
- (LSAnimator *)easeInQuint;
- (LSAnimator *)easeOutQuint;
- (LSAnimator *)easeInOutQuint;
- (LSAnimator *)easeInSine;
- (LSAnimator *)easeOutSine;
- (LSAnimator *)easeInOutSine;
- (LSAnimator *)easeInExpo;
- (LSAnimator *)easeOutExpo;
- (LSAnimator *)easeInOutExpo;
- (LSAnimator *)easeInCirc;
- (LSAnimator *)easeOutCirc;
- (LSAnimator *)easeInOutCirc;
- (LSAnimator *)easeInElastic;
- (LSAnimator *)easeOutElastic;
- (LSAnimator *)easeInOutElastic;
- (LSAnimator *)easeInBack;
- (LSAnimator *)easeOutBack;
- (LSAnimator *)easeInOutBack;
- (LSAnimator *)easeInBounce;
- (LSAnimator *)easeOutBounce;
- (LSAnimator *)easeInOutBounce;
这些函数的快速查看可以在这里找到
这些动画函数从可以在这里找到的酷炫关键帧动画库中提取
它们基于可以在这里找到的jQuery缓动函数
锚点
- (LSAnimator *)anchorDefault;
- (LSAnimator *)anchorCenter;
- (LSAnimator *)anchorTop;
- (LSAnimator *)anchorBottom;
- (LSAnimator *)anchorLeft;
- (LSAnimator *)anchorRight;
- (LSAnimator *)anchorTopLeft;
- (LSAnimator *)anchorTopRight;
- (LSAnimator *)anchorBottomLeft;
- (LSAnimator *)anchorBottomRight;
多链动画
您可以通过调用 concurrency
方法添加新的动画链,这不会影响之前的动画链。
animator.increWidth(20).spring.animateWithRepeat(0.5, 3);
animator.concurrent.makeBackground([UIColor orangeColor]).animate(1);
在新动画链同时运行之前,请不要更改动画链的属性。
// Do not do this
animator.moveX(20).animate(1.0);
animator.concurrent.moveX(-20).animate(1.0);
待办
- 约束动画器
安装
Cocoapods
Objective-C
- 将代码
pod 'LSAnimator', '~> 2.1.3'
添加到 Podfile。 - 运行
pod install
或pod update
。 - 添加代码
#import <LSAnimator/LSAnimator.h>
。
Swift
- 将代码
pod 'CoreAnimator', '~> 2.1.3'
添加到 Podfile。 - 运行
pod install
或pod update
。 - 添加代码
import CoreAnimator
。
Carthage
- 将
github "Lision/LSAnimator" ~> 2.1.3
添加到您的Cartfile中。 - 运行
carthage update --platform ios
。
Objective-C
将LSAnimator
框架添加到您的项目中。
Swift
将CoreAnimator
框架添加到您的项目中。
手动
可以克隆仓库并手动将文件添加到LSAnimator中。
要求
- LSAnimator 需要
iOS 7.0+
。 - CoreAnimator 需要
iOS 9.0+
。
联系
- 邮箱: [email protected]
- 新浪微博: @Lision
- Twitter: @Lision
许可
LSAnimator 按MIT许可提供。有关详细信息,请参阅LICENSE文件。