当前位置: 代码迷 >> Iphone >> iPhone实现QQ等app中右拖动银屏返回上一层视图切换的效果(继承UINavigationController)
  详细解决方案

iPhone实现QQ等app中右拖动银屏返回上一层视图切换的效果(继承UINavigationController)

热度:135   发布时间:2016-04-25 05:48:10.0
iPhone实现QQ等app中右拖动屏幕返回上一层视图切换的效果(继承UINavigationController)

实现腾讯qq,新浪微博,网易等app中右拖动返回上一层的效果demo。

首先看一下效果图:

???????


?首先要理解UIWindow,UIWindow对象是所有UIView的根,管理和协调的应用程序的显示
?UIWindow类是UIView的子类,可以看作是特殊的UIView。
?一般应用程序只有一个UIWindow对象,即使有多个UIWindow对象,也只有一个UIWindow可以接受到用户的触屏事件。?

?

[cpp]?view plaincopy
  1. //window窗口??
  2. #define?WINDOW??[[UIApplication?sharedApplication]keyWindow]??

?

?

第一步:要在UIView上添加一个pan拖动的手势,并添加处发方法handlePanGesture;

?

[cpp]?view plaincopy
  1. //拖动手势??
  2. ????UIPanGestureRecognizer?*panGesture=[[UIPanGestureRecognizer?alloc]initWithTarget:self?action:@selector(handlePanGesture:)];??
  3. ????//添加手势??
  4. ????[self.view?addGestureRecognizer:panGesture];??

?

第二步:handlePanGesture方法中首先判断是不是顶级视图,是return,如果不是需要返回上一层;

首先定义所需变量:

?

[cpp]?view plaincopy
  1. @interface?MyNavigationViewController?()??
  2. {??
  3. ????CGPoint?startTouch;//拖动时的开始坐标??
  4. ????BOOL?isMoving;//是否在拖动中??
  5. ????UIView?*blackMask;//那层黑面罩??
  6. ??????
  7. ????UIImageView?*lastScreenShotView;//截图??
  8. ??
  9. }??
  10. @property?(nonatomic,retain)?UIView?*backgroundView;//背景??
  11. @property?(nonatomic,retain)?NSMutableArray?*screenShotsList;//存截图的数组??
  12. ??
  13. ??
  14. @end??

?

然后是handlePanGesture方法处理:

?

[cpp]?view plaincopy
  1. //拖动手势??
  2. -(IBAction)handlePanGesture:(UIGestureRecognizer*)sender{??
  3. ??
  4. ????//如果是顶级viewcontroller,结束??
  5. ????if?(self.viewControllers.count?<=?1)?return;??
  6. ??
  7. ????//得到触摸中在window上拖动的过程中的xy坐标??
  8. ????CGPoint?translation=[sender?locationInView:WINDOW];??
  9. ????//状态结束,保存数据??
  10. ????if(sender.state?==?UIGestureRecognizerStateEnded){??
  11. ????????NSLog(@"结束%f,%f",translation.x,translation.y);??
  12. ????????isMoving?=?NO;??
  13. ??
  14. ????????self.backgroundView.hidden?=?NO;??
  15. ????????//如果结束坐标大于开始坐标50像素就动画效果移动??
  16. ????????if?(translation.x?-?startTouch.x?>?50)?{??
  17. ????????????[UIView?animateWithDuration:0.3?animations:^{??
  18. ????????????????//动画效果,移动??
  19. ????????????????[self?moveViewWithX:320];??
  20. ????????????}?completion:^(BOOL?finished)?{??
  21. ????????????????//返回上一层??
  22. ????????????????[self?popViewControllerAnimated:NO];??
  23. ????????????????//并且还原坐标??
  24. ????????????????CGRect?frame?=?self.view.frame;??
  25. ????????????????frame.origin.x?=?0;??
  26. ????????????????self.view.frame?=?frame;??
  27. ????????????}];??
  28. ??????????????
  29. ????????}else{??
  30. ????????????//不大于50时就移动原位??
  31. ????????????[UIView?animateWithDuration:0.3?animations:^{??
  32. ????????????????//动画效果??
  33. ????????????????[self?moveViewWithX:0];??
  34. ????????????}?completion:^(BOOL?finished)?{??
  35. ????????????????//背景隐藏??
  36. ????????????????self.backgroundView.hidden?=?YES;??
  37. ????????????}];??
  38. ????????}??
  39. ????????return;??
  40. ??????????
  41. ????}else?if(sender.state?==?UIGestureRecognizerStateBegan){??
  42. ????????NSLog(@"开始%f,%f",translation.x,translation.y);??
  43. ????????//开始坐标??
  44. ????????startTouch?=?translation;??
  45. ????????//是否开始移动??
  46. ????????isMoving?=?YES;??
  47. ????????if?(!self.backgroundView)??
  48. ????????{??
  49. ????????????//添加背景??
  50. ????????????CGRect?frame?=?self.view.frame;??
  51. ????????????self.backgroundView?=?[[UIView?alloc]initWithFrame:CGRectMake(0,?0,?frame.size.width?,?frame.size.height)];??
  52. ????????????//把backgroundView插入到Window视图上,并below低于self.view层??
  53. ????????????[WINDOW?insertSubview:self.backgroundView?belowSubview:self.view];??
  54. ??????????????
  55. ????????????//在backgroundView添加黑色的面罩??
  56. ????????????blackMask?=?[[UIView?alloc]initWithFrame:CGRectMake(0,?0,?frame.size.width?,?frame.size.height)];??
  57. ????????????blackMask.backgroundColor?=?[UIColor?blackColor];??
  58. ????????????[self.backgroundView?addSubview:blackMask];??
  59. ????????}??
  60. ????????self.backgroundView.hidden?=?NO;??
  61. ??
  62. ????????if?(lastScreenShotView)?[lastScreenShotView?removeFromSuperview];??
  63. ??????????
  64. ????????//数组中最后截图??
  65. ????????UIImage?*lastScreenShot?=?[self.screenShotsList?lastObject];??
  66. ????????//并把截图插入到backgroundView上,并黑色的背景下面??
  67. ????????lastScreenShotView?=?[[UIImageView?alloc]initWithImage:lastScreenShot];??
  68. ????????[self.backgroundView?insertSubview:lastScreenShotView?belowSubview:blackMask];??
  69. ??????????
  70. ????}??
  71. ??????
  72. ????if?(isMoving)?{??
  73. ????????[self?moveViewWithX:translation.x?-?startTouch.x];??
  74. ??
  75. ????}??
  76. }??

?

?

以上代码实现的是在UIWindow上放一个屏幕大小的UIView *backgroundView,并且这个UIView要插入到UIWindow视图里当前UIVIew的下面,这个方法是[WINDOW insertSubview:self.backgroundView belowSubview:self.view];
然后在backgroundView上要两个view:

UIView *blackMask;//那层黑面罩
UIImageView *lastScreenShotView;//截屏图

在拖动中不断的改变blackMask透明值,改变lastScreenShotView缩放大小:

?

[cpp]?view plaincopy
  1. -?(void)moveViewWithX:(float)x??
  2. {??
  3. ??????
  4. ????NSLog(@"Move?to:%f",x);??
  5. ????x?=?x>320?320:x;??
  6. ????x?=?x<0?0:x;??
  7. ??????
  8. ????CGRect?frame?=?self.view.frame;??
  9. ????frame.origin.x?=?x;??
  10. ????self.view.frame?=?frame;??
  11. ??????
  12. ????float?scale?=?(x/6400)+0.95;//缩放大小??
  13. ????float?alpha?=?0.4?-?(x/800);//透明值??
  14. ??????
  15. ????//缩放scale??
  16. ????lastScreenShotView.transform?=?CGAffineTransformMakeScale(scale,?scale);??
  17. ????//背景颜色透明值??
  18. ????blackMask.alpha?=?alpha;??
  19. ??????
  20. }??

?

?另外要把当前屏转化成图片的方法,UIView转成UIImage

?

[cpp]?view plaincopy
  1. //把UIView转化成UIImage,实现截屏??
  2. -?(UIImage?*)ViewRenderImage??
  3. {??
  4. ????//创建基于位图的图形上下文?Creates?a?bitmap-based?graphics?context?with?the?specified?options.:UIGraphicsBeginImageContextWithOptions(CGSize?size,?BOOL?opaque,?CGFloat?scale),size大小,opaque是否透明,不透明(YES),scale比例缩放??
  5. ????UIGraphicsBeginImageContextWithOptions(self.view.bounds.size,?self.view.opaque,?0.0);??
  6. ?????
  7. ????//当前层渲染到上下文??
  8. ????[self.view.layer?renderInContext:UIGraphicsGetCurrentContext()];??
  9. ??
  10. ????//上下文形成图片??
  11. ????UIImage?*?img?=?UIGraphicsGetImageFromCurrentImageContext();??
  12. ????//结束并删除当前基于位图的图形上下文。??
  13. ????UIGraphicsEndImageContext();??
  14. ????//反回图片??
  15. ????return?img;??
  16. }??

?

第三步:当push的时候,需要把当前图片添加存到数组中;当pop的时候,需要把最后一个图片移除。
?

?

[cpp]?view plaincopy
  1. #pragma?UINavigationController?覆盖方法??
  2. -(void)pushViewController:(UIViewController?*)viewController?animated:(BOOL)animated??
  3. {??
  4. ????//图像数组中存放一个当前的界面图像,然后再push??
  5. ????[self.screenShotsList?addObject:[self?ViewRenderImage]];??
  6. ??
  7. ????[super?pushViewController:viewController?animated:animated];??
  8. }??
  9. ??
  10. -(UIViewController?*)popViewControllerAnimated:(BOOL)animated??
  11. {??
  12. ????//移除最后一个??
  13. ????[self.screenShotsList?removeLastObject];??
  14. ????return?[super?popViewControllerAnimated:animated];??
  15. }??

?

?

?

Demo下载地址:http://download.csdn.net/detail/rhljiayou/5979139

参考:http://blog.csdn.net/rhljiayou/article/details/10096347

  相关解决方案