LSAnimator - 易于读写的多链式动画框架

4,100 阅读5分钟

LSAnimator

易于读写的多链式动画框架 (完美支持 Swift 3.2 - 4.0)

GitHub:LSAnimator

为什么选择 LSAnimator?

通过使用 LSAnimator(Objective-C)或者 CoreAnimator(Swift)可以用少量的代码实现复杂而又易于维护的动画。

为了提供友好的 Swift 使用体验我新建了一个独立的 Framework - CoreAnimator,与 LSAnimator 具有同样强大的功能。

为什么要写 LSAnimator?

嘛~ 其实一开始是为了自己使用哈。

早在去年,所在项目为了优化交互做了比较多的动画,在实现这些动画的时候不论是用 CAAnimations 还是 UIView animations 都要写冗长的代码。这样的代码不但书写的时候手累,维护的时候心也会累,而且由于每一处的动画交互都有差异,加上日后可能需要随时修改动画交互细节,所以一直想弄一个动画库来解放我浪费在写动画交互实现方面的劳动力。

写库之前先去 GitHub 上搜了一下,发现一个动画库 JHChainableAnimations 号称易于读写的可链式动画框架,所以就直接拿来用了。

不过在使用的过程中发现这个库有一个致命的缺陷,就是所有动画都必须放在一条动画链上,执行完一个再去执行下一个。可是在实际的使用中,我发现很多动画需求都是一条动画链跑不下来的。

所以我当时就在它的基础上提升了一个维度,把可链式升级为了多链式。使用至今还没遇到过多链式动画无法实现的动画需求,所以应该算是高可定制化的动画库了(笑)。

之后本来想给 JHChainableAnimations 提 PR 的,但是发现它当时已经改版到 v2.0 了。Emmmmm...本来升级为多链式改动的代码就很大,加上我当时改动的代码是 v1.0 的版本,合并代码时非常痛苦...索性就自己在 GitHub 上开了一个项目。嘛~ 就是现在的 LSAnimator。

之后也收到了一些 Issues,也有在积极的维护,现在已经和 JHChainableAnimations 的差距不断拉大了(感觉写框架是一种乐趣,维护框架是另一种)。

什么是多链式动画?

CAAnimations 和 UIView animations 已经非常强大了,但是当动画设计稍微复杂一些时使用它们去实现会让代码变得非常难以阅读和维护。

假设我想用 spring 时间曲线将 myView 右移 100 点,移动完成之后再用 EaseIn 时间曲线将 myView 的宽度增加 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];
                     }];

Emmmmm...这代码很难阅读,而且不利于维护。

嘛~ 用 LSAnimator 可以一行代码搞定。

Using LSAnimator

LSAnimator *animator = [LSAnimator animatorWithView:self.myView];
animator.moveX(100).spring.thenAfter(2).increWidth(30).easeIn.animate(2);

Emmmmm...不过已经有一个名为 JHChainableAnimations 的动画库了,使用它也可以做到这一点。

那么 JHChainableAnimations 存在哪些问题呢?

JHChainableAnimations 具有强大的可链接式动画,并且语法易于读/写,但是它不支持多链式动画

接着上面的例子,假设现在维持上面的动画需求不变,新加入需求要使 myView 的透明度在上面动画的整个执行过程中改为 0:

LSAnimator

用 LSAnimator 实现的话仅需要添加一行代码即可。

LSAnimator *animator = [LSAnimator animatorWithView:self.myView];
animator.moveX(100).spring.thenAfter(2).increWidth(30).easeIn.animate(2);
// Add this line
animator.concurrent.makeOpacity(0).animate(4);

JHChainableAnimations

Emmmmm...使用 JHChainableAnimations 是不能完成这项任务的。尝试添加下面的代码将会引起动画表现异常甚至闪退。效果就如上面所示,myView 闪了一下透明度直接变为了 0,这显然不是我们想要的效果。

JHChainableAnimator *animator = [[JHChainableAnimator alloc] initWithView:self.myView];
animator.moveX(100).spring.thenAfter(2).moveWidth(30).easeIn.animate(2);
animator.makeOpacity(0).animate(4);

LSAnimator VS JHChainableAnimations

  • 多链式动画: 可以实现几乎所有的动画设计,比 JHChainableAnimations 灵活而且强大(高了一个维度)。
  • 支持 CALayer: 支持通过 CALayer 初始化,可以直接操作 CALayer 实现动画, JHChainableAnimations 仅支持 UIView。
  • 参数自动补全: 支持参数自动补全,自动提示所需参数的数量和所属类型,JHChainableAnimations 并不支持。

LSAnimator 在 . 语法后跟出的方法中自带了参数提示,包含参数的数量和所属类型

JHChainableAnimations 在 . 语法后跟出的方法并没有参数提示,使用起来很不方便,特别是不熟悉参数的时候需要 command + left mouse 跟代码才能确认所需参数的数量和类型:

嘛~ 关于更多的内容和使用说明 LSAnimator 项目介绍已经写得很详细了~

最后

如果你已经看到这里了,那么无论如何还请进项目页面看一下哈!

项目初期,欢迎 PR!


补充~ 我建了一个技术交流微信群,想在里面认识更多的朋友!如果各位同学对文章有什么疑问或者工作之中遇到一些小问题都可以在群里找到我或者其他群友交流讨论,期待你的加入哟~

Emmmmm..由于微信群人数过百导致不可以扫码入群,所以请扫描上面的二维码关注公众号进群。