JHChainableAnimations 源码阅读

来源:互联网 发布:网络图片 拍摄时间 编辑:程序博客网 时间:2024/05/21 15:06

JHChainableAnimations 源码阅读(2)

JHChainableAnimations 支持链式编程。链式编程 在OC中的实现就是,函数返回一个Block,并且在外面调用这个block,传入block计算所需要的参数。并且block返回对象本身,这样子就可以继续调用了

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

Masonry 自动布局的框架也是链式编程有空继续分析

UIView (UIView_JHChainableAnimations)定义了一些UIView的常用操作

改变大小OR位移

- (JHChainableRect) makeFrame;- (JHChainableRect) makeBounds;- (JHChainableSize) makeSize;- (JHChainablePoint) makeOrigin;- (JHChainablePoint) makeCenter;- (JHChainableFloat) makeX;- (JHChainableFloat) makeY;- (JHChainableFloat) makeWidth;- (JHChainableFloat) makeHeight;- (JHChainableFloat) makeOpacity;- (JHChainableColor) makeBackground;- (JHChainableColor) makeBorderColor;- (JHChainableFloat) makeBorderWidth;- (JHChainableFloat) makeCornerRadius;- (JHChainableFloat) makeScale;- (JHChainableFloat) makeScaleX;- (JHChainableFloat) makeScaleY;- (JHChainablePoint) makeAnchor;

……

接下来分析一个具体的实现看看比如

makeFrame

-(JHChainableRect)makeFrame {JHChainableRect chainable = JHChainableRect(rect){    return self.makeOrigin(rect.origin.x, rect.origin.y).makeBounds(rect);    };    return chainable;}

>
JHChainableRect block 传入参数 CGRectrect 然后调用 self.makeOrigin 修改Origin 再调用makeBounds 修改大小

-(JHChainablePoint)makeOrigin {    JHChainablePoint chainable = JHChainablePoint(x, y) {        //修改position        [self addAnimationCalculationAction:^(UIView *weakSelf) {            JHKeyframeAnimation *positionAnimation = [weakSelf basicAnimationForKeyPath:@"position"];            CGPoint newPosition = [weakSelf newPositionFromNewOrigin:CGPointMake(x, y)];            positionAnimation.fromValue = [NSValue valueWithCGPoint:weakSelf.layer.position];            positionAnimation.toValue = [NSValue valueWithCGPoint:newPosition];            [weakSelf addAnimationFromCalculationBlock:positionAnimation];        }];        //动画结束结束之后,修改最终的结果        [self addAnimationCompletionAction:^(UIView *weakSelf) {            CGPoint newPosition = [weakSelf newPositionFromNewOrigin:CGPointMake(x, y)];            weakSelf.layer.position = newPosition;        }];        return self;    };    return chainable;}    -(JHChainableRect)makeBounds {    JHChainableRect chainable = JHChainableRect(rect) {        //修改大小        return self.makeSize(rect.size.width, rect.size.height);    };    return chainable;}- (JHChainableSize) makeSize {    JHChainableSize chainable = JHChainableSize(width, height){        [self addAnimationCalculationAction:^(UIView *weakSelf) {        //动画核心编程        //keyPath bounds.size            JHKeyframeAnimation *sizeAnimation = [weakSelf basicAnimationForKeyPath:@"bounds.size"];            sizeAnimation.fromValue = [NSValue valueWithCGSize:weakSelf.layer.bounds.size];            sizeAnimation.toValue = [NSValue valueWithCGSize:CGSizeMake(width, height)];            //加入动画数组            [weakSelf addAnimationFromCalculationBlock:sizeAnimation];        }];        //执行完了的结果添加到当前的Layer上,不然会返回初始状态        [self addAnimationCompletionAction:^(UIView *weakSelf) {            CGRect bounds = CGRectMake(0, 0, width, height);            weakSelf.layer.bounds = bounds;            weakSelf.bounds = bounds;        }];        //返回当前对象,可以链式调用        return self;    };    return chainable;}

把动画加入到动画数组

-(void) addAnimationCalculationAction:(JHAnimationCalculationAction)action {    NSMutableArray *actions = [self.JHAnimationCalculationActions lastObject];    [actions addObject:action];}

把动画结果加入到结果的数组中

-(void) addAnimationCompletionAction:(JHAnimationCompletionAction)action {    NSMutableArray *actions = [self.JHAnimationCompletionActions lastObject];    [actions addObject:action];}

JHAnimationCalculationActions通过关联把数组设置为当前对象的属性 其他数组一样。

如何调用的呢?

比如:self.myView.moveX(50).animate(.25);通过moveX 把动画 过程添加到动画数组,之后通过animate 调用,把动画添加到 CAAnimationGroup对象中,然后,再加入到当前的layer

-(JHChainableAnimation)animate {    JHChainableAnimation chainable = JHChainableAnimation(duration) {        //从 CAAnimationGroup 数组中拿出最后一个CAAnimationGroup对象        CAAnimationGroup *group = [self.JHAnimationGroups lastObject];        //设置动画需要的时间        group.duration = duration;        [self animateChain];        return self;    };    return chainable;}-(void) animateChain {    [self sanityCheck];    //提交事务    [CATransaction begin];    [CATransaction setDisableActions:YES];    [CATransaction setCompletionBlock:^{ //一组动画完成之后的事情        [self.layer removeAnimationForKey:@"AnimationChain"];        [self chainLinkDidFinishAnimating];    }];    //执行动画    [self animateChainLink];    [CATransaction commit];    [self executeCompletionActions];}-(void) animateChainLink {    [self makeAnchorFromX:0.5 Y:0.5];    //动画过程传入参数    NSMutableArray *actionCluster = [self.JHAnimationCalculationActions firstObject];    for (JHAnimationCalculationAction action in actionCluster) {    //防止循环引用        __weak UIView *weakSelf = self;        action(weakSelf);    }    CAAnimationGroup *group = [self.JHAnimationGroups firstObject];    NSMutableArray *animationCluster = [self.JHAnimations firstObject];    for (JHKeyframeAnimation *animation in animationCluster) {        animation.duration = group.duration;        [animation calculate];    }    //把一组动画加入到CAAnimationGroup 来    group.animations = animationCluster;    //添加动画    [self.layer addAnimation:group forKey:@"AnimationChain"];    // 自动布局属性的    NSTimeInterval delay = MAX(group.beginTime - CACurrentMediaTime(), 0.0);    [self.class animateWithDuration:group.duration                              delay:delay                            options:0                         animations:^{        [self updateConstraints];    } completion:nil];}

执行过程大概就是这样子!睡了,明天有空继续分析。分析完这个库,核心动画编程会了一大半了。

0 0
原创粉丝点击