先看看动画效果:
项目结构:
接下来开始具体实现过程:
一、先计算动画开始结束位置
方法:
- (CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view;
用该方法计算动画view相对于window的位置
1) 计算动画开始位置fromCenter
CGPoint fromCenter = [animationView convertPoint:CGPointMake(animationView.frame.size.width * 0.5f, animationView.frame.size.height * 0.5f) toView:keyWindow];
2)计算动画结束位置endCenter
CGPoint endCenter = [endView convertPoint:CGPointMake(endView.frame.size.width * 0.5f, endView.frame.size.height * 0.5f) toView:keyWindow];
二、计算贝塞尔曲线(抛物线)的两个控制点
用UIBezierPath 画出抛物线,需要找到两个控制点controlPoint1 和 controlPoint2
controlPoint1
是控制点1controlPoint2
是控制点2A
是controlPoint1
和controlPoint2
的中点controlPointC
是fromCenter
和B
的中点
1)先设置控制点距最高点(fromCenter
或endCenter
)的水平距离controlPointEY
,本篇默认controlPointEY = 100
,即图1中点controlPointC
到点A
的距离。
2)计算控制点相对于点A
的距离controlPointEX
,即controlPoint1
到A
距离或controlPoint2
到A
距离,本篇设置为fromCenter.x
到endCenter.x
的1/4,即controlPointEX = (endCenter.x - fromCenter.x) * 0.25f;
3)计算两个控制点位置
CGPoint controlPoint1 = CGPointMake(controlPointCX - controlPointEX, controlPointCY - controlPointEY);
CGPoint controlPoint2 = CGPointMake(controlPointCX + controlPointEX, controlPointCY - controlPointEY);
三、复制动画的layer
复制cell上需要做动画的view,add到window上做动画
NSString *str = ((UIButton *)animationView).titleLabel.text;
_animationLayer = [CATextLayer layer];
_animationLayer.bounds = animationView.bounds;
_animationLayer.position = fromCenter;
_animationLayer.alignmentMode = kCAAlignmentCenter;//文字对齐方式
_animationLayer.wrapped = YES;
_animationLayer.contentsScale = [UIScreen mainScreen].scale;
_animationLayer.string = str;
_animationLayer.backgroundColor = [UIColor redColor].CGColor;
[keyWindow.layer addSublayer:_animationLayer];
四、动画组合
整合所有动画,让view动起来
1)运动轨迹(抛物线)
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:fromCenter];
[path addCurveToPoint:endCenter controlPoint1:controlPoint1 controlPoint2:controlPoint2];
CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
pathAnimation.path = path.CGPath;
2)旋转起来
CABasicAnimation *rotateAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
rotateAnimation.removedOnCompletion = YES;
rotateAnimation.fromValue = [NSNumber numberWithFloat:0];
rotateAnimation.toValue = [NSNumber numberWithFloat:10 * M_PI];
rotateAnimation.timingFunction=[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]
3)缩放动画
CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
scaleAnimation.removedOnCompletion = NO;
scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0];
scaleAnimation.toValue = [NSNumber numberWithFloat:0.2];
4)透明度动画
CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
alphaAnimation.removedOnCompletion = NO;
alphaAnimation.fromValue = [NSNumber numberWithFloat:1.0];
alphaAnimation.toValue = [NSNumber numberWithFloat:0.1];
5)动画组合
CAAnimationGroup *groups = [CAAnimationGroup animation];
groups.animations = @[pathAnimation,rotateAnimation, scaleAnimation, alphaAnimation];
groups.duration = kShoppingCartDuration;
groups.removedOnCompletion=NO;
groups.fillMode=kCAFillModeForwards;
groups.delegate = self;
[_animationLayer addAnimation:groups forKey:@"group"];
五、其他
iOS 购物车动画
注:本文著作权归作者,由demo大师代发,拒绝转载,转载需要作者授权