iOS 添加商品到购物车的动画实现

简介: iOS 添加商品到购物车的动画实现
  • 1.1 下载地址
  • 2.1  商品的cell
  • 2.2 开(下)单界面
  • 2.3  下单商品的控制器VC
  • 2.4 动画处理工具类 JoinCartAnimationTool

引言


将商品图片icon 移动到购物车iocn的位置的动画效果:

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

I、demo下载

1.1 下载地址

从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中

image.png

BillingRightCell.m

  • 添加商品按钮的动画处理
[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

  • 处理动画事件
#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

  • 处理动画
[_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];
        }];
  • 处理动画的工具类属性
@property (strong, nonatomic) JoinCartAnimationTool *AnimationTool;
- (JoinCartAnimationTool *)AnimationTool{
    if (nil == _AnimationTool) {
        QCTJoinCartAnimationTool *tmpView = [[JoinCartAnimationTool alloc]init];
        _AnimationTool = tmpView;
    }
    return _AnimationTool;
}

2.4 动画处理工具类 JoinCartAnimationTool

.h

/**
 @param imageView 移动的View: 例如商品图片
 @param boxImgV view移动的最后目标视图: 例如购物车icon控件
 @param inView  imageView  boxImgV 参考的坐标系。例如购物车VC的View
 */
-(void)joinCartAnimationWithView:(UIImageView *)imageView toView:(UIView*)boxImgV inView:(UIView*)inView;

.m

#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


1、会员详情的右侧下拉操作菜单

image.png

2、浏览器的右侧下拉菜单

image.png

3、原文:https://kunnan.blog.csdn.net/article/details/84618986

4、demo下载地址:https://download.csdn.net/download/u011018979/16092830

5、相关文章:利用锚点anchorPoint进行实现

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

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

目录
相关文章
|
iOS开发
iOS 动画绘制圆形
iOS 动画绘制圆形
114 1
|
编译器 iOS开发 异构计算
读iOS核心动画笔记
读iOS核心动画笔记
73 0
|
4月前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户点击按钮时,按钮将从圆形变为椭圆形,颜色从蓝色渐变到绿色;释放按钮时,动画以相反方式恢复。通过UIView的动画方法和弹簧动画效果,实现平滑自然的过渡。
105 1
|
5月前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
【10月更文挑战第18天】本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户按下按钮时,按钮将从圆形变为椭圆形并从蓝色渐变为绿色;释放按钮时,动画恢复原状。通过UIView的动画方法和弹簧动画效果,实现平滑自然的动画过渡。
89 5
|
6月前
|
Swift iOS开发 UED
揭秘一款iOS应用中令人惊叹的自定义动画效果,带你领略编程艺术的魅力所在!
【9月更文挑战第5天】本文通过具体案例介绍如何在iOS应用中使用Swift与UIKit实现自定义按钮动画,当用户点击按钮时,按钮将从圆形变为椭圆形并从蓝色渐变到绿色,释放后恢复原状。文中详细展示了代码实现过程及动画平滑过渡的技巧,帮助读者提升应用的视觉体验与特色。
100 11
|
7月前
|
Swift iOS开发 UED
【绝妙创意】颠覆你的视觉体验!揭秘一款iOS应用中令人惊叹的自定义动画效果,带你领略编程艺术的魅力所在!
【8月更文挑战第13天】本文通过一个具体案例,介绍如何使用Swift与UIKit在iOS应用中创建独特的按钮动画效果。当按钮被按下时,其形状从圆形变化为椭圆形,颜色则从蓝色渐变为绿色;释放后,动画反向恢复原状。利用UIView动画方法及弹簧动画效果,实现了平滑自然的过渡。通过调整参数,开发者可以进一步优化动画体验,增强应用的互动性和视觉吸引力。
82 7
|
iOS开发
iOS 常用阅读软件打开书籍的转场动画
iOS 常用阅读软件打开书籍的转场动画
122 0
|
10月前
|
iOS开发
iOS设备功能和框架: 如何使用 Core Animation 创建动画效果?
iOS设备功能和框架: 如何使用 Core Animation 创建动画效果?
160 0
|
API iOS开发
iOS 自定义转场动画 UIViewControllerTransitioning
iOS 自定义转场动画 UIViewControllerTransitioning
150 0
|
API iOS开发
iOS 核心动画
iOS 核心动画
94 0

热门文章

最新文章

  • 1
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
  • 2
    iOS|解决 setBrightness 调节屏幕亮度不生效的问题
  • 3
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 4
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
  • 5
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
  • 6
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
  • 7
    iOS各个证书生成细节
  • 8
    uniapp云打包ios应用证书的获取方法,生成指南
  • 9
    iOS|记一名 iOS 开发新手的前两次 App 审核经历
  • 10
    【iOS-cocos2d-X 游戏开发之十】自定义各类模版&触屏事件讲解!
  • 1
    uniapp云打包ios应用证书的获取方法,生成指南
    27
  • 2
    iOS|解决 setBrightness 调节屏幕亮度不生效的问题
    117
  • 3
    iOS|记一名 iOS 开发新手的前两次 App 审核经历
    20
  • 4
    iOS各个证书生成细节
    35
  • 5
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    157
  • 6
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    55
  • 7
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    73
  • 8
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    54
  • 9
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    65
  • 10
    uniapp开发ios打包Error code = -5000 Error message: Error: certificate file(p12) import failed!报错问题如何解决
    171