美文网首页iOS@IT·互联网程序员
CoreAnimation之贝塞尔曲线(加入购物车动画)

CoreAnimation之贝塞尔曲线(加入购物车动画)

作者: 雪_晟 | 来源:发表于2017-01-03 18:11 被阅读482次
    12.gif

    加入购物车这个动画关键是贝塞尔曲线的绘制,然后给购物车加上一个关键帧动画即可。

    贝塞尔曲线的起点从cell 中button开始,到购物车位置结束,控制点取 起点的纵坐标,终点的横坐标。
    因为不在一个坐标系内,所以我们需要转换:

    - (CGPoint)convertPoint:(CGPoint)point toView:(nullable UIView *)view;
    - (CGPoint)convertPoint:(CGPoint)point fromView:(nullable UIView *)view;
    - (CGRect)convertRect:(CGRect)rect toView:(nullable UIView *)view;
    - (CGRect)convertRect:(CGRect)rect fromView:(nullable UIView *)view;
    

    在这里我们把购物车以及 cell 上的加入购物车按钮 全部转换到selv.view上(ps:本来想把购物车的中心点转化到tableview,上,把动画封装在cell的button 点击事件里,可是失败了, 代理方法会走,但是没有动画效果😢)

    cell 中的回调处理

     [self layoutIfNeeded];//xib初始化,需要获得正确的frame
        
        CGPoint carButtonCenter = sender.center;
        
        //把button在cell坐标转化为在tableView上的坐标
        CGPoint point = [self convertPoint:carButtonCenter toView:self.superview.superview];
        
        //回调
        if (_shoppingButtonBlock)
        {
            _shoppingButtonBlock(point);
        }
    

    viewcontroller中的处理

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        MyCell *cell =[tableView dequeueReusableCellWithIdentifier:cellId];
        if (!cell) {
            cell =[[MyCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
            
        }
        __weak ViewController *weakSelf = self;
        [cell setShoppingButtonBlock:^(CGPoint centerPoint) {
            //关键帧动画处理
            [weakSelf startAnimate:centerPoint];
        }];
       
        return cell;
    }
    
    

    可以把CAShapeLayer去掉,只是为了直观的看到动画效果

    -(void)startAnimate:(CGPoint)centerPoint
    {
        //起点
        CGPoint startPoint = [self.tableview convertPoint:centerPoint toView:self.view];;
        CGPoint endpoint = self.shopView.center;
        //控点
        CGPoint controlPoint = CGPointMake(endpoint.x, startPoint.y);
        
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:startPoint];
        [path addQuadCurveToPoint:endpoint controlPoint:controlPoint];
        
        CAShapeLayer *layer =[CAShapeLayer layer];
        layer.path = path.CGPath;
        layer.fillColor = [UIColor clearColor].CGColor;
        layer.strokeColor = [UIColor redColor].CGColor;
        layer.lineWidth = 3.0f;
        layer.shouldRasterize = YES;//抗锯齿
        [self.view.layer addSublayer:layer];
        
        //创建关键帧
        CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        
        //动画时间
        animation.duration = 1;
        animation.path = path.CGPath
        ;
        //当动画完成,停留到结束位置
        animation.removedOnCompletion = YES;
        animation.fillMode = kCAFillModeForwards;
        animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        
        [self.shopView.layer addAnimation:animation forKey:nil];
        path = nil;
        
    }
    
    

    还是将动画抽取出来,只需要起点和终点以及动画宿主视图,实现解耦。

    定义一个NSObject类,接口如下:

    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    @interface AddToShopAnimation : NSObject
    -(instancetype)initWithStartPoint:(CGPoint)startPoint entPoint:(CGPoint)endPoint ViewController:(UIViewController *)viewController HostView:(UIView *)shopView;
    -(void)startAnimation;
    @end
    
    -(void)startAnimation
    {
        //起点
        
        //控点
        CGPoint controlPoint = CGPointMake(_endPoint.x, _startPoint.y);
        
        UIBezierPath *path = [UIBezierPath bezierPath];
        [path moveToPoint:_startPoint];
        [path addQuadCurveToPoint:_endPoint controlPoint:controlPoint];
        
        CAShapeLayer *layer =[CAShapeLayer layer];
        layer.path = path.CGPath;
        layer.fillColor = [UIColor clearColor].CGColor;
        layer.strokeColor = [UIColor redColor].CGColor;
        layer.lineWidth = 3.0f;
        layer.shouldRasterize = YES;//抗锯齿
        [_viewController.view.layer addSublayer:layer];
        
        //创建关键帧
        CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        
        //动画时间
        animation.duration = 1;
        animation.path = path.CGPath
        ;
        //当动画完成,停留到结束位置
        animation.removedOnCompletion = YES;
        animation.fillMode = kCAFillModeForwards;
        animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
        [_shopView.layer addAnimation:animation forKey:nil];
        path = nil;
    
    }
    

    demo地址:贝塞尔曲线之加入购物车

    相关文章

      网友评论

        本文标题:CoreAnimation之贝塞尔曲线(加入购物车动画)

        本文链接:https://www.haomeiwen.com/subject/fpsnvttx.html