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];
}
执行过程大概就是这样子!睡了,明天有空继续分析。分析完这个库,核心动画编程会了一大半了。
本文详细解析了JHChainableAnimations库的链式编程实现方式,包括链式调用的具体方法如makeFrame、makeBounds等,并介绍了如何通过链式调用实现UIView的动画效果。

378

被折叠的 条评论
为什么被折叠?



