iOS 商品旋转加入购物车动画,并附带抖动效果

97 篇文章 0 订阅
19 篇文章 1 订阅

最近在开发一个商城类app,需要一个加入购物车一个动画效果,自己写会很麻烦,我就在网上找了一些资料最后实现了想要的效果,这个实现主要就是iOS提供的动画库:CAAnimation

实现效果如下:

下面就是实现代码,只有一个类PurchaseCarAnimationTool

.h文件

typedef void (^animationFinisnBlock)(BOOL finish);
#define ScreenWidth [UIScreen mainScreen].bounds.size.width
#define ScreenHeight [UIScreen mainScreen].bounds.size.height
@interface PurchaseCarAnimationTool : NSObject
@property (strong , nonatomic) CALayer *layer;
@property (copy , nonatomic) animationFinisnBlock animationFinisnBlock;
/**
 *  初始化
 *
 *  @return <#return value description#>
 */
+ (instancetype)shareTool;
/**
 *  开始动画
 *
 *  @param view        添加动画的view
 *  @param rect        view 的绝对frame
 *  @param finishPoint 下落的位置
 *  @param finishBlock 动画完成回调
 */
- (void)startAnimationandView:(UIView *)view
                         rect:(CGRect)rect
                  finisnPoint:(CGPoint)finishPoint
                  finishBlock:(animationFinisnBlock)completion;
/**
 *  摇晃动画
 *
 *  @param shakeView <#shakeView description#>
 */
+ (void)shakeAnimation:(UIView *)shakeView;
@end

下面是.m文件


#import "PurchaseCarAnimationTool.h"

@interface PurchaseCarAnimationTool()<CAAnimationDelegate>

@end

@implementation PurchaseCarAnimationTool
#pragma mark - instancetype
+ (instancetype)shareTool
{
    return [[PurchaseCarAnimationTool alloc]init];
}
#pragma public function
- (void)startAnimationandView:(UIView *)view
                         rect:(CGRect)rect
                  finisnPoint:(CGPoint)finishPoint
                  finishBlock:(animationFinisnBlock)completion
{
    //图层
    _layer = [CALayer layer];
    _layer.contents = view.layer.contents;
    _layer.contentsGravity = kCAGravityResizeAspectFill;
    rect.size.width  = rect.size.width;
    rect.size.height = rect.size.height;   //重置图层尺寸
    _layer.bounds = rect;
//    _layer.cornerRadius  = rect.size.width/2;
//    _layer.masksToBounds = YES;          //圆角
    UIWindow *keyWindow = [UIApplication sharedApplication].keyWindow;
    [keyWindow.layer addSublayer:_layer];
    _layer.position = CGPointMake(rect.origin.x+view.frame.size.width/2, CGRectGetMidY(rect)); //a 点
    /// 路径
    [self createAnimationwithRect:rect finishPoint:finishPoint];
    /// 回调
    if (completion) {
        _animationFinisnBlock = completion;
    }
}
+ (void)shakeAnimation:(UIView *)shakeView
{
    CABasicAnimation *shakeAnimation = [CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
    shakeAnimation.duration = 0.25f;
    shakeAnimation.fromValue = [NSNumber numberWithFloat:-5];
    shakeAnimation.toValue = [NSNumber numberWithFloat:5];
    shakeAnimation.autoreverses = YES;
    [shakeView.layer addAnimation:shakeAnimation forKey:nil];
    
}
#pragma mark - private function
/// 创建动画
- (void)createAnimationwithRect:(CGRect)rect
                    finishPoint:(CGPoint)finishPoint {
    /// 路径动画
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:_layer.position];
    [path addQuadCurveToPoint:finishPoint controlPoint:CGPointMake(ScreenWidth/2, rect.origin.y-80)];
    CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    pathAnimation.path = path.CGPath;
    /// 旋转动画
    CABasicAnimation *rotateAnimation   = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
    rotateAnimation.removedOnCompletion = YES;
    rotateAnimation.fromValue = [NSNumber numberWithFloat:0];
    rotateAnimation.toValue   = [NSNumber numberWithFloat:12];
    rotateAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    
    /// 缩放动画
    CABasicAnimation *scaleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    scaleAnimation.removedOnCompletion = YES;
    scaleAnimation.fromValue = [NSNumber numberWithFloat:1.0]; // 开始时的倍率
    scaleAnimation.toValue = [NSNumber numberWithFloat:0.25]; // 结束时的倍率
    scaleAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
    
    /// 添加动画动画组合
    CAAnimationGroup *groups = [CAAnimationGroup animation];
    groups.animations = @[pathAnimation,rotateAnimation,scaleAnimation];
    groups.duration = 1.0f;
    groups.removedOnCompletion = NO;
    groups.fillMode = kCAFillModeForwards;
    groups.delegate = self;
    [_layer addAnimation:groups forKey:@"group"];
}

#pragma mark - CAAnimationDelegate
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    if (anim == [_layer animationForKey:@"group"]) {
        [_layer removeFromSuperlayer];
        _layer = nil;
        if (_animationFinisnBlock) {
            _animationFinisnBlock(YES);
        }
    }
}
@end

我是swift项目,这里使用是方式自然是swift语音风格。那么我们如何使用呢?

首先是加入购物车动画

let wCell = collectionView.cellForItem(at: indexPath)// 获取点击的第几个Cell
            var rect = wCell?.frame
            // 获取当前cell 相对于self.view 当前的坐标
            rect!.origin.y = (rect?.origin.y)! - collectionView.contentOffset.y
            var imageViewRect = imageView.frame
            imageViewRect.origin.x = (rect?.origin.x)!
            imageViewRect.origin.y = (rect?.origin.y)! + imageViewRect.origin.y
            PurchaseCarAnimationTool.share()?.startAnimationandView(imageView, rect: imageViewRect, finisnPoint: CGPoint(x: kScreenWidth / 4 * 2.5, y: kScreenHeight - CGFloat(SafeAreaTopHeight)), finish: { (finish:Bool) in
               if (self.tabBarController as AnyObject).isKind(of:MyTabBarController.classForCoder()) {
                    //此处就是另一个动画加入购物车抖动动画
PurchaseCarAnimationTool.shakeAnimation(self.tabBarController!.tabBar.subviews[3]);
               }
            })

以上便是整个动画的实现效果,希望对大家有所帮助

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王 哪跑!!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值