前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS动画之【添加商品到购物车】:将商品图片icon 移动到购物车iocn的位置

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

作者头像
公众号iOS逆向
发布2023-09-11 08:58:35
1750
发布2023-09-11 08:58:35
举报
文章被收录于专栏:iOS逆向与安全iOS逆向与安全

引言

效果: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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-08-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 iOS逆向 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • I、demo下载
  • II 、代码实现
    • 2.1 商品的cell
      • 2.2 开(下)单界面
        • 2.3 下单商品的控制器VC
          • 2.4 动画处理工具类 JoinCartAnimationTool
          • see also
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档