iOS 仿淘宝加入购物车前选择尺寸,规格弹窗的向内凹陷折叠动画效果和标签流布局

   项目中做了一套电商的购物流程,很多都是照着淘宝做的,之前一直疑惑淘宝的弹框

时,底部的控制器向内凹陷是什么鬼,这动画有点理解不了,一直就放着没有做,这周

突然在github上看到一个老外写的库,真的有点强啊,我这里简单写了个Demo给大家分析下,然后再用这个牛B的库集成下展示最终成果


老规矩,看图说话,一个是自己写的Demo,一个是通过库展示给大家      


在介绍库之前先自己写个Demo捋一捋思路

第一个View:根部控制器,我们设置为黑色


第二个View:根部VC上面加载另一个用来做动画的AnimationVC (addChildViewController)


第三个View:在AnimationVC上面add一个MaskView


第四个View:最后就是弹出的最终popView(加载到Window上面,类似于系统的Alert or sheet)


第一步:布局View

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. // 设置底部的背景颜色 (第一层)  
  2.     self.view.backgroundColor = [UIColor blackColor];  
  3.       
  4.     // 设置AnimationVC的属性 (第二层)  
  5.     self.mkjVC = [[MKJAnimationViewController alloc] init];  
  6.     self.mkjVC.view.backgroundColor = [UIColor whiteColor];  
  7.     self.mkjVC.view.frame = CGRectMake(00, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height);  
  8.     self.mkjVC.title = @"Animation";  
  9.     self.nvc = [[UINavigationController alloc] initWithRootViewController:self.mkjVC];  
  10.   
  11.     [self addChildViewController:self.nvc];  
  12.     [self.view addSubview:self.nvc.view];  
  13.     // 设置开始按钮  
  14.     UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];  
  15.     [button setTitle:@"show" forState:UIControlStateNormal];  
  16.     [button setTitleColor:[UIColor purpleColor] forState:UIControlStateNormal];  
  17.     [button addTarget:self action:@selector(clickShow:) forControlEvents:UIControlEventTouchUpInside];  
  18.     button.frame = CGRectMake(0010030);  
  19.     button.center = self.nvc.view.center;  
  20.     [self.nvc.view addSubview:button];  
  21.       
  22.     // 设置maskView (第三层)  
  23.     self.maskView = [[UIView alloc] initWithFrame:self.mkjVC.view.bounds];  
  24.     self.maskView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];  
  25.     self.maskView.alpha = 0;  
  26.     [self.nvc.view addSubview:self.maskView];  
  27.       
  28.     // 设置popVIew (第四层)  
  29.     self.popView = [[UIView alloc] initWithFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height / 2)];  
  30.     self.popView.backgroundColor = [UIColor redColor];  
  31.     self.popView.layer.shadowColor = [UIColor blackColor].CGColor;  
  32.     self.popView.layer.shadowOffset = CGSizeMake(33);  
  33.     self.popView.layer.shadowOpacity = 0.8;  
  34.     self.popView.layer.shadowRadius = 5.0f;  
  35.       
  36.     // closeButton  
  37.     UIButton *button1 = [UIButton buttonWithType:UIButtonTypeCustom];  
  38.     [button1 setTitle:@"Cancel" forState:UIControlStateNormal];  
  39.     [button1 setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];  
  40.     button1.frame = CGRectMake(5510030);  
  41.     [button1 addTarget:self action:@selector(close:) forControlEvents:UIControlEventTouchUpInside];  
  42.     [self.popView addSubview:button1];  

第二步:形变动画(最关键,分两段)

先解释下M34是什么东西

transform本身就是个结构体,首先要实现View的透视效果(近大远小),就是通过它来实现的

CATransform3D rotationAndPerspectiveTransform = CATransform3DIdentity;

rotationAndPerspectiveTransform.m34 = 1.0 / -500;


m34负责z轴方向的translation(移动),m34= -1/D,  默认值是0,也就是说D无穷大,这意味layer in projection plane(投射面)和layer in world coordinate重合了。


D越小透视效果越明显。所谓的D,是eye(观察者)到投射面的距离


形变1

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. // 第一次形变  
  2. - (CATransform3D)transform1{  
  3.     // 每次进来都进行初始化 回归到正常状态  
  4.     CATransform3D form1 = CATransform3DIdentity;  
  5.     // m34就是实现视图的透视效果的(俗称近大远小)  
  6.     form1.m34 = 1.0/-900;  
  7.     //缩小的效果  
  8.     form1 = CATransform3DScale(form10.950.951);  
  9.     //x轴旋转  
  10.     form1 = CATransform3DRotate(form115.0 * M_PI/180.0100);  
  11.     return form1;  
  12.       
  13. }  

形变2

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. // 第二次形变  
  2. - (CATransform3D)transform2{  
  3.     // 初始化 再次回归正常  
  4.     CATransform3D form2 = CATransform3DIdentity;  
  5.     // 用上面用到的m34 来设置透视效果  
  6.     form2.m34 = [self transform1].m34;  
  7.     //向上平移一丢丢 让视图平滑点  
  8.     form2 = CATransform3DTranslate(form20self.view.frame.size.height * (-0.08), 0);  
  9.     //最终再次缩小到0.8倍  
  10.     form2 = CATransform3DScale(form20.80.81);  
  11.     return form2;  
  12. }  



第三步:动画的开始和结束

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. // 点击动画开始  
  2. - (void)clickShow:(UIButton *)button  
  3. {  
  4.     // 开始的时候把popView加载到window上面去,类似于系统的actionSheet之类的弹窗  
  5.     [[UIApplication sharedApplication].windows[0] addSubview:self.popView];  
  6.     // 先计算出popView的弹出高度  
  7.     CGRect rec = self.popView.frame;  
  8.     rec.origin.y = self.view.bounds.size.height / 2;  
  9.     [UIView animateWithDuration:0.3 animations:^{  
  10.         // 先逆时针X轴旋转 缩小到0.95呗,向内凹陷的透视效果 如果不进行下一波操作,那么这个效果就是View向内倾斜了  
  11.         self.nvc.view.layer.transform = [self transform1];  
  12.     } completion:^(BOOL finished) {  
  13.         // 倾斜完之后,我们再进行第二段操作,先把transform设置为初始化,然后透视还是和第一段一样,让他回归到正常(不倾斜)同时让大小动画为0.8,高度向上移动一点点,maskView出来,popView也顺着出来指定高度  
  14.         [UIView animateWithDuration:0.3 animations:^{  
  15.               
  16.             self.nvc.view.layer.transform = [self transform2];  
  17.             self.maskView.alpha = 0.5;  
  18.             self.popView.frame = rec;  
  19.         } completion:^(BOOL finished) {  
  20.         }];  
  21.     }];  
  22. }  

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. // 动画关闭  
  2. - (void)close:(UIButton *)button  
  3. {  
  4.     // 先计算出popView回去的位置  
  5.     CGRect rec = self.popView.frame;  
  6.     rec.origin.y = self.view.bounds.size.height;  
  7.       
  8.     // 动画回去  
  9.     [UIView animateWithDuration:0.4 animations:^{  
  10.         // popView回去  
  11.         self.popView.frame = rec;  
  12.         // mask回0  
  13.         self.maskView.alpha = 0;  
  14.         // 在进行旋转,向内凹陷,大小缩为0.95倍  
  15.         self.nvc.view.layer.transform = [self transform1];  
  16.           
  17.     } completion:^(BOOL finished) {  
  18.           
  19.         // 折叠完之后让transform回归到正常水平就好了  
  20.         [UIView animateWithDuration:0.3 animations:^{  
  21.               
  22.             self.nvc.view.layer.transform = CATransform3DIdentity;  
  23.               
  24.         } completion:^(BOOL finished) {  
  25.               
  26.             // 把popView从Window中移除  
  27.             [self.popView removeFromSuperview];  
  28.               
  29.         }];  
  30.           
  31.     }];  
  32.       
  33. }  

    Demo就这样,该有的效果就出来了,大伙可以自己试试



OK,现在来个成熟的框架,效果那肯定是杠杠的KNSemiModalViewController点击打开链接

先看看官方给出的效果图



可以弹控制器也可以弹View,自定义非常高

-(void)presentSemiViewController:(UIViewController*)vc;

-(void)presentSemiViewController:(UIViewController*)vc withOptions:(NSDictionary*)options;

-(void)presentSemiView:(UIView*)vc;

-(void)presentSemiView:(UIView*)view withOptions:(NSDictionary*)options;


首先:导入source里面的两个文件,在需要的地方包含这个类扩展

然后:把需要弹出来的信息写在另一个控制器里面,直接在想要弹的地方调用

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. [self.navigationController presentSemiViewController:self.chooseVC withOptions:@{  
  2.                                                                KNSemiModalOptionKeys.pushParentBack    : @(YES),  
  3.                                                                KNSemiModalOptionKeys.animationDuration : @(2.0),  
  4.                                                                KNSemiModalOptionKeys.shadowOpacity     : @(0.3),  
  5.                                                                KNSemiModalOptionKeys.backgroundView : [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background_01"]]  
  6.                                                                }];  

喂喂喂,结束了么,我刚买了瓜子和饮料来看???你就给我看这个?

没错,结束了,各回各家,各找各妈,瓜子和饮料都给我吧


噢,对了,弹出来的View里面的tag布局传送门 点击打开链接tag布局


这里大家用库的时候绝对会遇到几个坑,最常见的给大家罗列下

1.问题一

ld: 1 duplicate symbol for architecture x86_64

clang: error: linker command failed with exit code 1 (use -v to see invocation)

方法:

add typedef

typedef NS_ENUM(NSUInteger, KNSemiModalTransitionStyle) {

KNSemiModalTransitionStyleSlideUp,

KNSemiModalTransitionStyleFadeInOut,

KNSemiModalTransitionStyleFadeIn,

KNSemiModalTransitionStyleFadeOut,

};


2.问题二

Exception: Defaults must have been set when accessing 

如果你要的根控制器是有导航栏的

[self.navigationController presentSemiViewController....

如果没有导航栏

[self presentSemiViewController....

不然我的做,你就飞了


可以了,再BB就要被打了


自己写的Demo:点击打开链接简单Demo


用库集成的超级Demo:点击打开链接超级Demo


tag标签布局传送:点击打开链接Tag



少年,点个赞再走好么,不会少块肉的。。。。。。


点你妹啊,你知道按一下鼠标有多累么!!??!?会触电的!!!


好吧。。。。。。

    


注意啦


如果你Push的时候没这么做,你的界面会

出BUG,下面是我的解决方案

[objc]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. - (void)show:(UITapGestureRecognizer *)tap  
  2. {  
  3.     if (!self.chooseVC)  
  4.     {  
  5.           
  6.         self.chooseVC = [[ChooseGoodsPropertyViewController alloc] init];  
  7.       
  8.     }  
  9.     self.chooseVC.enterType = FirstEnterType;  
  10.     __weak typeof(self)weakSelf = self;  
  11.     self.chooseVC.block = ^{  
  12.   
  13.         NSLog(@"点击回调去购物车");  
  14.         // 下面一定要移除,不然你的控制器结构就乱了,基本逻辑层级我们已经写在上面了,这个效果其实是addChildVC来的,最后的展示是在Window上的,一定要移除  
  15.         [weakSelf.chooseVC.view removeFromSuperview];  
  16.         [weakSelf.chooseVC removeFromParentViewController];  
  17.         weakSelf.chooseVC.view = nil;  
  18.         weakSelf.chooseVC = nil;  
  19.           
  20.         MKJShoppingCartViewController *shop = [MKJShoppingCartViewController new];  
  21.         [weakSelf.navigationController pushViewController:shop animated:YES];  
  22.           
  23.     };  
  24.     self.chooseVC.price = 256.0f;  
  25.     [self.navigationController presentSemiViewController:self.chooseVC withOptions:@{  
  26.                                                                                      KNSemiModalOptionKeys.pushParentBack    : @(YES),  
  27.                                                                                      KNSemiModalOptionKeys.animationDuration : @(0.6),  
  28.                                                                                      KNSemiModalOptionKeys.shadowOpacity     : @(0.3),  
  29.                                                                                      KNSemiModalOptionKeys.backgroundView : [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"background_01"]]  
  30.                                                                                     }];  
  31. }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值