IOS实现翻转一个View显示presentVi…

本文介绍了一种在iOS中实现点击视图翻转并展示新ViewController内容的动画效果。通过将目标ViewController内容渲染为图片,然后创建新视图进行翻转动画,最终呈现出类似翻转卡片的效果。在实际开发中需要注意视图的帧设置、渲染问题以及Layer的Z轴索引等细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近看到了一个比较好看的动画效果,就是通过点击了一个View,被点击的View会被翻转过来,然后在其背面显示出另一个ViewController的内容。就像一张两面的板子被翻转一样。于是在最近的项目里面就写了下这个效果:

  







思路是这样的,先将被显示的ViewController的内容渲染到一张图片上去。

然后在window上面添加一个新的View将被点的View的内容渲染成图片后显示在此新建的View上,并且调整新建的view的位置。

隐藏被点View,然后开始反转动画。为了简单起见动画分为2步,第一步为旋转90度。第二步开始反向旋转90度,但是在开始之前将ViewController的图片显示在该View上。

最后将Viewcontroller Present出来就好了。


具体看代码吧

给UIViewController建一个Category,这样使用就很方便了。

所有代码在下面:

 

[html]  view plain copy
  1. (void)flipView:(UIView *)view toPresentViewController:(UIViewController *)controller completion:(void (^)(void))completion  
  2.     [self retain];  
  3.     [view retain];  
  4.     [controller retain];  
  5.     //调整大小  
  6.     UIWindow *window [UIApplication sharedApplication].keyWindow;  
  7.     CGRect frame window.frame;  
  8.     frame.size.height -20 
  9.     frame.origin.y 20 
  10.     controller.view.frame frame 
  11.     [controller.view layoutIfNeeded];  
  12.     //预渲染一遍  
  13.     [self presentViewController:controller animated:NO completion:nil];  
  14.     [controller dismissViewControllerAnimated:NO completion:0];  
  15.       
  16.     //获取将要显示的 View 的 Image  
  17.     UIGraphicsBeginImageContextWithOptions(controller.view.frame.size, controller.view.opaque, 0.0);  
  18.     [controller.view.layer renderInContext:UIGraphicsGetCurrentContext()];  
  19.     UIImage *viewControllerImage UIGraphicsGetImageFromCurrentImageContext();  
  20.     UIGraphicsEndImageContext();  
  21.     //保存被翻转的View 的 Image  
  22.     UIGraphicsBeginImageContextWithOptions(view.frame.size, view.opaque, 0.0);  
  23.     [view.layer renderInContext:UIGraphicsGetCurrentContext()];  
  24.     UIImage *viewImgae UIGraphicsGetImageFromCurrentImageContext();  
  25.     UIGraphicsEndImageContext();  
  26.       
  27.     //坐标转化  
  28.     frame view.frame;  
  29.     UIView *parentView view.superview;  
  30.     if (parentView == window)  
  31.     }else{  
  32.         UIView *parentParentView parentView.superview;  
  33.         while (parentParentView&&parentView&&(parentView != self.view&&parentParentView != window))  
  34.             frame [parentParentView convertRect:frame fromView:parentView];  
  35.             parentView=parentParentView 
  36.             parentParentView parentParentView.superview;  
  37.          
  38.      
  39.     frame [window convertRect:frame fromView:parentView];  
  40.       
  41.     //包裹旋转的View  
  42.     UIView      *imageLayout=[[UIView alloc]initWithFrame:window.bounds];  
  43.     UIImageView *imageView [[UIImageView alloc]initWithFrame:frame];  
  44.     [imageView setImage:viewImgae];  
  45.       
  46.     [imageLayout addSubview:imageView];  
  47.     [window addSubview:imageLayout];  
  48.       
  49.     [imageLayout release];  
  50.     [imageView release];  
  51.       
  52.       
  53.     CATransform3D rotationTransform CATransform3DMakeRotation(M_PI*1.0f/2.0f, 0, 1, 0);  
  54.       
  55.     [view setHidden:YES];  
  56.     //投影矩阵  
  57.     CATransform3D perspective CATransform3DIdentity 
  58.     perspective.m34 -1.0/800.0;  
  59.     imageLayout .layer.sublayerTransform perspective 
  60.     imageLayout .layer .zPosition 2000 
  61.       
  62.     [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{  
  63.           
  64.         imageView.layer.transform rotationTransform 
  65.           
  66.     completion:^(BOOL finished)  
  67.         [imageView setImage:viewControllerImage];  
  68.         imageView.layer.transform CATransform3DMakeRotation(-M_PI*1.0f/2.0f, 0, 1, 0);  
  69.           
  70.         [UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{  
  71.             imageView.layer.transform CATransform3DIdentity 
  72.               
  73.             CGRect frame window.frame;  
  74.             frame.size.height -20 
  75.             frame.origin.y 20 
  76.             imageView.frame  frame;  
  77.         completion:^(BOOL finished)  
  78.             [self presentViewController:controller animated:NO completion:completion];  
  79.               
  80.             [imageLayout removeFromSuperview];  
  81.             [view setHidden:NO];  
  82.             [view release];  
  83.             [self release];  
  84.             [controller release];  
  85.   
  86.   
  87.         }];  
  88.           
  89.     }];  
  90.  

 


这个版本也刚刚算能用吧,bug肯定是有的。


实际开发过程中还是有很多问题的,本人将开发中遇到的一些问题一起说下吧。

第一个就是恶心的渲染ViewController,首先从xib出来的view的frame很奇怪,有的时候只能人肉设置frame,还有就是当ViewController为Navigation时,如果给Navigation设过Appearance,如果不先经过present一下会有点显示的bug,就是appearance无效。


然后就是关于layer的zIndex的问题了,为了有立体效果,需要有点投射效果,即zIndex不能乱设。大家都知道zIndex小的layer会被zIndex大的layer遮住,但是我比较傻,一开始旋转的view总是只能显示一半,最后才发现原来会被遮住。

然后就想着提升zIndex,但是我已开始是将投射矩阵设在window上面,这样的话View的立体效果特别强,都快戳瞎狗眼了。苦于无解的时候突然想到可以用一个新的View把旋转的包起来,给那个View设置较大的zIndex,并且设置投射矩阵,结果就解决了问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值