JHChainableAnimations 源码阅读
2016-07-02 18:47
429 查看
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;
[/code]
……
接下来分析一个具体的实现看看比如
makeFrame
-(JHChainableRect)makeFrame { JHChainableRect chainable = JHChainableRect(rect){ return self.makeOrigin(rect.origin.x, rect.origin.y).makeBounds(rect); }; return chainable; }
>
JHChainableRectblock 传入参数
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.t 4000 oValue = [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; }]; [code]//返回当前对象,可以链式调用
return self;
};
return chainable;
}
[/code]
把动画加入到动画数组
-(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]; }
执行过程大概就是这样子!睡了,明天有空继续分析。分析完这个库,核心动画编程会了一大半了。