iOS购物车动画实现
1.动画效果图
![](https://img.haomeiwen.com/i1940819/4bf7a4ccab0ac038.gif)
2.动画分析
购物车动画主要用了核心动画中的关键帧动画,即CAKeyframeAnimation, 购物车动画的path是一条贝塞尔曲线,所以我们的重点就是构建一条这样的贝塞尔曲线即可,系统为我们提供了2个path类,一个是封装好的UIBezierPath, 一个是C语言的CGMutablePathRef结构体。其实这两个类都可以实现,我们只需要使用其中的一种就可以了。
3.核心代码
其实每个cell上都有一个“加入购物车按钮”,当点击按钮,我们需要在自定义的cell里面进行坐标系转化,因为按钮相对于自己的cell,我们的最终效果就是,无论tableView的偏移量是多少,当点击加入购物车按钮,就从当前按钮的中心点出发到购物车终点进行动画。
所以在Cell.m里面,按钮触发事件里面代码如下:
![](http://upload-images.jianshu.io/upload_images/1940819-2a561da185dd86c0.png)
这个里面用到convertPoint:toView:方法,可以这样理解:[A convertPoint:point toView:B], 表示point点相对于A坐标系的点转化到B坐标系上位置,方法返回的也是一个点。就好比我们相对于一个参照物的位置是point1,参考另外一个参照物的位置就是point2,参照物不一样,位置肯定也不一样。所以在进行动画的过程中,我们先把动画的起点和终点转化到同一个坐标系上,即控制器的view.
4.构造贝塞尔曲线
下面先了解下贝塞尔曲线
![](http://upload-images.jianshu.io/upload_images/1940819-06bd2ae17d612454.gif)
这是一个二阶贝塞尔曲线,一个曲线大概有3部分组成:起点、终点、控点。上图中Po就是起点,P1是控点,P2是终点。当控点变化时,曲线也会跟着变化。
PS:控点就是起点和终点切线的交点。
购物车动画我们可以构成一个这样的贝塞尔曲线:
![](http://upload-images.jianshu.io/upload_images/1940819-b90833772f147a8d.png)
构造的贝塞尔曲线
如上图,P0是起点,P2是终点,P1就是P0和P2切线的交点,即控点。
/**
* 动画的终点
*/
CGPoint _endPoint = btn.center;
Cell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
[cell setShoppingCarButtonDidClickHandle:^(CGPoint centerPoint) {
//起点
CGPoint startPoint = [tableView convertPoint:centerPoint toView:self.view];
//控点
CGPoint controlPoint = CGPointMake(_endPoint.x, startPoint.y);
//创建一个layer
CALayer *layer = [CALayer layer];
layer.frame = CGRectMake(0, 0, 40, 40);
layer.position = centerPoint;
layer.backgroundColor = [UIColor redColor].CGColor;
layer.cornerRadius = layer.frame.size.width/2;
layer.masksToBounds = YES;
[self.view.layer addSublayer:layer];
//创建关键帧
CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
animation.delegate = self;
//动画时间
animation.duration = 5;
//当动画完成,停留到结束位置
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
//当方法名字遇到create,new,copy,retain,都需要管理内存
CGMutablePathRef path = CGPathCreateMutable();
//设置起点
CGPathMoveToPoint(path, NULL, startPoint.x, startPoint.y);
CGPathAddQuadCurveToPoint(path, NULL, controlPoint.x, controlPoint.y, _endPoint.x, _endPoint.y);
//设置动画路径
animation.path = path;
//执行动画
[layer addAnimation:animation forKey:nil];
//释放路径
CGPathRelease(path);
}];
Demo的github地址: https://github.com/qindeli/--ShoppingCarAnimation