JHChainableAnimations源码学习

JHChainableAnimations源码学习

JHChainableAnimations是什么

JHChainableAnimations 是一个多系统动画封装的链式语法库。

原有的OC代码如果我们想写一个动画,需要这样写。

    [UIView animateWithDuration:1.0
                          delay:0.0
         usingSpringWithDamping:0.8
          initialSpringVelocity:1.0
                        options:0 animations:^{
                            CGPoint newPosition = self.myView.frame.origin;
                            newPosition.x += 50;
                            self.myView.frame.origin = newPosition;
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.5
                              delay:0.0
                            options:UIViewAnimationOptionCurveEaseIn
                         animations:^{
            self.myView.backgroundColor = [UIColor purpleColor];
        } completion:nil];
    }];

使用 JHChainableAnimations 可以这样写:

JHChainableAnimator *animator = [[JHChainableAnimator alloc] initWithView:self.myView];
animator.moveX(50).spring.thenAfter(1.0).makeBackground([UIColor purpleColor]).easeIn.animate(0.5);

代码一下就显得特别清晰明了,JHChainableAnimations 采用了现在流行的链式语法,跟 Masonry 一样的语法。

链式语法的特点是什么

链式编程特点:方法的返回值是block,block必须有返回值(本身对象),block参数(需要操作的值)

JHChainableAnimations代码具体分析

首先看一段代码

JHChainableAnimator *animator = [[JHChainableAnimator alloc] initWithView:self.myView];
animator.moveX(100).animate(2);

首先是将 self.myViewJHChainableAnimator *animator 关联起来,然后通过 JHChainableAnimator *animator 进行动画设置。

第二行代码
animator.moveX(100).animate(2);

首先是 animator 调用 moveX 方法生成动画样式,这个方法从字面上面看 就是 移动视图的X轴,然后调用 animate 执行动画,设置动画时间。具体看先 它是如何实现的。

- (JHChainableFloat)moveX
{
    JHChainableFloat chainable = JHChainableFloat(f) {
        
        [self addAnimationCalculationAction:^(__weak UIView *view, __weak JHChainableAnimator *weakSelf) {
            JHKeyframeAnimation *positionAnimation = [weakSelf basicAnimationForKeyPath:@"position.x"];
            positionAnimation.fromValue = @(view.layer.position.x);
            positionAnimation.toValue = @(view.layer.position.x+f);
            [weakSelf addAnimationFromCalculationBlock:positionAnimation];
        }];
        [self addAnimationCompletionAction:^(__weak UIView *view, __weak JHChainableAnimator *weakSelf) {
            CGPoint position = view.layer.position;
            position.x += f;
            view.layer.position = position;
        }];
        
        return self;
    };
    return chainable;
}

再来回顾下链式语法的特点:

方法的返回值是block,block必须有返回值(本身对象),block参数(需要操作的值)

再来看上面这段代码:

  1. moveX 方法返回的是一个 block chainable
  2. block 的参数是一个 float
  3. block chainable 的返回值是当前类 JHChainableAnimator 实例。

完全符合链式语法的特点。

moveX 具体实现

然后再来看具体实现,moveX 干了什么。

首先是返回了一个 block,然后这个 block 返回了这个类本身的实例。

block chainable 都做了什么
  1. 生成一个可执行的动画
     [self addAnimationCalculationAction:^(__weak UIView *view, __weak JHChainableAnimator *weakSelf) {
            JHKeyframeAnimation *positionAnimation = [weakSelf basicAnimationForKeyPath:@"position.x"];
            positionAnimation.fromValue = @(view.layer.position.x);
            positionAnimation.toValue = @(view.layer.position.x+f);
            [weakSelf addAnimationFromCalculationBlock:positionAnimation];
        }];
  1. 生成有个动画执行完毕的回调,修改视图属性
    [self addAnimationCompletionAction:^(__weak UIView *view, __weak JHChainableAnimator *weakSelf) {
            CGPoint position = view.layer.position;
            position.x += f;
            view.layer.position = position;
        }];
  1. 返回 当前类本身

animate 具体实现

- (JHChainableAnimation)animate
{
    JHChainableAnimation chainable = JHChainableAnimation(t) {
        
        return self.animateWithCompletion(t, self.completionBlock);
    };
    
    return chainable;
}

华丽的分割线

感觉自己的语言表示能力有问题,突然不知道该怎么往下说下去了。
这个地方。

重新描述下:

首先是像

- (JHChainableFloat)moveX;
- (JHChainableFloat)moveY;
- (JHChainablePoint)moveXY;
- (JHChainableFloat)moveHeight;
- (JHChainableFloat)moveWidth;

这类方法调用的时间,会生成一些类的动画对象 JHKeyframeAnimation 然后存储到 JHAnimationChainLink 的动画数组里面。

最终 animate 方法是循环调用 类数组里面存储的 JHAnimationChainLink 对象,执行 JHAnimationChainLink 对象的 JHKeyframeAnimation动画数组。
大致就是这样执行的,但是具体的实现有好多细节,动画的添加,动画执行的回调,取得当前执行的动画、如何暂停动画等。感觉自己目前的功力还很难描述清楚。就暂时先告一段落了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 那棵枫树呢 我在这里等 等了一百年 终究没有从前的颜色 . 这个季节除了枯枝 没有什么可以编织花环 你用什么来暗示...
    周延龙阅读 105评论 1 5
  • 怪鸭帆说:每个人都有一个餐厅的梦。在这个连载里,将用我的亲身经历告诉年轻人,如何开自己的第一家餐厅。这个连载将是一...
    怪鸭帆阅读 685评论 4 7
  • 杨绛先生说我们总是想的太多,读书太少 我在想一个问题的时候,总是时不时的走神。所以往往一天下来,做成的事情很少,但...
    木头与琉璃阅读 246评论 0 0
  • flask框架第一部,创建一个项目flask是python中一个微内核的web框架 开发环境 python3.6f...
    那个唐僧阅读 2,949评论 0 4
  • 会议纪要是在总结中夹杂着陈述,而且还能够让所有参会者看后感到自己价值体现的一种文体。不知我总结的对不对,反正我是认...
    刚刚的钢阅读 4,357评论 0 4