iOS动画之【添加商品到购物车】:将商品图片icon 移动到购物车iocn的位置

2023-09-11 08:58:35 浏览数 (1)

引言

效果:https://live.csdn.net/v/embed/167358

demo下载地址:https://download.csdn.net/download/u011018979/20045082

视频:http://mpvideo.qpic.cn/0bf2tqaecaaa2qalghgsavqfbhgdigoaaqia.f10002.mp4?

应用场景:购物车模块,将商品添加商品到购物车

如果是扫商品条码添加购物车,推荐延迟1.5S再重新识别。

代码语言:javascript复制
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                [weakSelf reStartDevice];
            });

I、demo下载

从CSDN下载Demo:https://download.csdn.net/download/u011018979/20045082

1、应用场景:购物车模块,将商品添加商品到购物车 2、文章地址:https://blog.csdn.net/z929118967/article/details/103660899 3、视频地址:https://live.csdn.net/v/167358

II 、代码实现

添加商品到购物车的事件传递,由cell->V->VC 核心处理代码在工具类JoinCartAnimationTool中

2.1 商品的cell

BillingRightCell.m

  • 添加商品按钮的动画处理
代码语言:javascript复制
    [self.counterV.animationSubject subscribeNext:^(UIButton *btn) {
        @strongify(self);
        if (btn) {
            if ([self.delegate respondsToSelector:@selector(performAnimationWithCell:buttonView:)]) {
                [self.delegate performAnimationWithCell:self buttonView:self.iconImgV];
            }
        }
    }];

2.2 开(下)单界面

BillingView

  • 处理动画事件
代码语言:javascript复制
#pragma mark - BillingRightCellDelegate
- (void)performAnimationWithCell:(BillingRightCell *)cell
                      buttonView:(UIImageView *)view
{
//    CGRect parentRect = [cell convertRect:view.frame toView:self];

    if (self.joinCartAnimationWithViewblock) {
        self.joinCartAnimationWithViewblock(view);
    }
    
}

2.3 下单商品的控制器VC

展示商品数据的VC:BillingViewController

  • 处理动画
代码语言:javascript复制
        [_vcView setJoinCartAnimationWithViewblock:^(id  _Nonnull sender) {

            //sender 即添加按钮的控件
            //btn.imageView:展示购物车icon的imageView
            //weakSelf.view:当前控制器的视图
            [[weakSelf AnimationTool] joinCartAnimationWithView:sender toView:weakSelf.topButtonView.shoppingBtn.btn.imageView inView:weakSelf.view];
            
        }];
        
  • 处理动画的工具类属性
代码语言:javascript复制
@property (strong, nonatomic) JoinCartAnimationTool *AnimationTool;
- (JoinCartAnimationTool *)AnimationTool{
    if (nil == _AnimationTool) {
        QCTJoinCartAnimationTool *tmpView = [[JoinCartAnimationTool alloc]init];
        _AnimationTool = tmpView;
    }
    return _AnimationTool;
}

2.4 动画处理工具类 JoinCartAnimationTool

.h

代码语言:javascript复制
/**
 
 
 @param imageView 移动的View: 例如商品图片
 @param boxImgV view移动的最后目标视图: 例如购物车icon控件
 @param inView  imageView  boxImgV 参考的坐标系。例如购物车VC的View
 */

-(void)joinCartAnimationWithView:(UIImageView *)imageView toView:(UIView*)boxImgV inView:(UIView*)inView;

.m

代码语言:javascript复制
#import "JoinCartAnimationTool.h"


@interface JoinCartAnimationTool ()

/**
 用于动画
 */
@property (strong, nonatomic) UIBezierPath *path;
@property (assign, nonatomic) CGFloat animationDuration;
@property (strong, nonatomic) CALayer *dotLayer;


//self.topButtonView.shoppingBtn.btn.imageView
@property (strong, nonatomic) UIView *endView;

@end

@implementation JoinCartAnimationTool


- (instancetype)init
{
    self = [super init];
    if (self) {
        self.animationDuration = 0.5f;

    }
    return self;
}




#pragma mark - ******** joinCartAnimationWithRect

/**
 
以inView为参考,计算开始位置和结束位置的rect
 @param imageView 移动的View: 例如商品图片
 @param boxImgV view移动的最后目标视图: 例如购物车icon控件
 @param inView  imageView  boxImgV 参考的坐标系。例如购物车VC的View
 */
-(void)joinCartAnimationWithView:(UIImageView *)imageView toView:(UIView*)boxImgV inView:(UIView*)inView
{
    self.endView = boxImgV;
    
    CGRect rect = [imageView.superview convertRect:imageView.frame toView:inView];
    
    CGRect endRect = [boxImgV.superview convertRect:boxImgV.frame toView:inView];
    
    CGPoint endPoint = CGPointMake(endRect.origin.x   endRect.size.width/2, endRect.origin.y   endRect.size.height/2);
    
    CGFloat startX = rect.origin.x rect.size.width/2;
    CGFloat startY = rect.origin.y rect.size.height/2;
    
    _path= [UIBezierPath bezierPath];
    [_path moveToPoint:CGPointMake(startX, startY)];
    
    [_path addLineToPoint:CGPointMake(endPoint.x, endPoint.y)];
    //    [_path addCurveToPoint:CGPointMake(endPoint.x, endPoint.y)
    //             controlPoint1:CGPointMake(startX, startY)
    //             controlPoint2:CGPointMake(startX - 180, startY - 200)];
    _dotLayer = [CALayer layer];
    //    _dotLayer.backgroundColor = [UIColor purpleColor].CGColor;
    NSData * tempArchive = [NSKeyedArchiver archivedDataWithRootObject:imageView];
    UIImageView *copyImgV = [NSKeyedUnarchiver unarchiveObjectWithData:tempArchive];
    UIImage *image = [self circleImage:copyImgV];
    _dotLayer.contents = (__bridge id)image.CGImage;
    _dotLayer.frame = imageView.frame;
    [inView.layer addSublayer:_dotLayer];
    [self groupAnimation];
}

-(UIImage *)circleImage:(UIImageView *)imageView{
    UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, NO, 0);
    [[UIBezierPath bezierPathWithOvalInRect:imageView.bounds] addClip];
    [imageView drawRect:imageView.bounds];
    imageView.image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return imageView.image;
}

-(void)groupAnimation
{
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    animation.path = _path.CGPath;
    animation.rotationMode = kCAAnimationLinear;
    
    CABasicAnimation *alphaAnimation1 = [CABasicAnimation animationWithKeyPath:@"bounds"];
    alphaAnimation1.duration = 0.1;
    alphaAnimation1.repeatCount = 1;
    alphaAnimation1.fromValue = [NSValue valueWithCGRect:CGRectMake(0, 0, _dotLayer.bounds.size.width*1.5, _dotLayer.bounds.size.height*1.5)];
    alphaAnimation1.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, _dotLayer.bounds.size.width, _dotLayer.bounds.size.height)];
    alphaAnimation1.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    [_dotLayer addAnimation:alphaAnimation1 forKey:@"bounds"];
    
    
    CABasicAnimation *alphaAnimation = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
    alphaAnimation.duration = self.animationDuration;
    alphaAnimation.fromValue = [NSNumber numberWithFloat:1.0];
    alphaAnimation.toValue = [NSNumber numberWithFloat:0.1];
    alphaAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    
    
    CAAnimationGroup *groups = [CAAnimationGroup animation];
    groups.animations = @[animation,alphaAnimation];
    groups.duration = self.animationDuration;
    groups.removedOnCompletion = NO;
    groups.fillMode = kCAFillModeForwards;
    groups.delegate = self;
    //    [groups setValue:@"groupsAnimation" forKey:@"animationName"];
    [_dotLayer addAnimation:alphaAnimation forKey:@"cornerRadius"];
    
    [_dotLayer addAnimation:groups forKey:nil];
    
    [self performSelector:@selector(removeFromLayer:) withObject:_dotLayer afterDelay:self.animationDuration];
    
    //    WS(weakSelf);
    //    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(self.animationDuration/2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    //        [weakSelf playingBoxAnimation];
    //    });
}

- (void)removeFromLayer:(CALayer *)layerAnimation{
    
    [layerAnimation removeFromSuperlayer];
}




#pragma mark - CAAnimationDelegate
- (void)animationDidStart:(CAAnimation *)anim{
    
}

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag
{
    
    // 完成可以使用比例动画scale
    UIView *endView = self.endView;
    
    CABasicAnimation *alphaAnimation1 = [CABasicAnimation animationWithKeyPath:@"bounds"];
    alphaAnimation1.duration = 0.1;
    alphaAnimation1.repeatCount = 1;
    alphaAnimation1.fromValue = [NSValue valueWithCGRect:CGRectMake(0, 0, endView.bounds.size.width*1.5, endView.bounds.size.height*1.5)];
    alphaAnimation1.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, endView.bounds.size.width, endView.bounds.size.height)];
    alphaAnimation1.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];
    [endView.layer addAnimation:alphaAnimation1 forKey:@"bounds"];
}


@end

see also

iOS Document Scanner:矩形边缘识别(边缘检测 ) CIDetectorTypeRectangle

https://kunnan.blog.csdn.net/article/details/117367345

0 人点赞