终于效果:

AnimatedNavigationController.h

//
//  AnimatedNavigationController.h
//  20_帅哥no微博
//
//  Created by beyond on 14-8-10.
//  Copyright (c) 2014年 com.beyond. All rights reserved.
//  继承自导航控制器,可是多了一个功能,能够监听手势,进行动画切换#import <UIKit/UIKit.h>@interface AnimatedNavigationController : UINavigationController@end

AnimatedNavigationController.m

//
//  AnimatedNavigationController.m
//  20_帅哥no微博
//
//  Created by beyond on 14-8-10.
//  Copyright (c) 2014年 com.beyond. All rights reserved.
//#import "AnimatedNavigationController.h"
// 截图用到
#import <QuartzCore/QuartzCore.h>
#import "BeyondViewController.h"
@interface AnimatedNavigationController ()
{// 屏幕截图UIImageView *_screenshotImgView;// 截图上面的黑色半透明遮罩UIView *_coverView;// 存放全部截图NSMutableArray *_screenshotImgs;
}@end@implementation AnimatedNavigationController- (void)viewDidLoad
{[super viewDidLoad];// 1,创建Pan手势识别器,并绑定监听方法UIPanGestureRecognizer *panGestureRec = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panGestureRec:)];// 为导航控制器的view加入Pan手势识别器[self.view addGestureRecognizer:panGestureRec];// 2.创建截图的ImageView_screenshotImgView = [[UIImageView alloc] init];// app的frame是除去了状态栏高度的frame_screenshotImgView.frame = [UIScreen mainScreen].applicationFrame;//(0 20; 320 460);// 3.创建截图上面的黑色半透明遮罩_coverView = [[UIView alloc] init];// 遮罩的frame就是截图的frame_coverView.frame = _screenshotImgView.frame;// 遮罩为黑色_coverView.backgroundColor = [UIColor blackColor];// 4.存放全部的截图数组初始化_screenshotImgs = [NSMutableArray array];}// 重写push方法,在push之前 先截取图片
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{// 仅仅有在导航控制器里面有子控制器的时候才须要截图if (self.viewControllers.count >= 1) {// 调用自己定义方法,使用上下文截图[self screenShot];}// 截图完毕之后,才调用父类的push方法[super pushViewController:viewController animated:YES];
}// 使用上下文截图,并使用指定的区域裁剪,模板代码
- (void)screenShot
{// 将要被截图的view,即窗体的根控制器的view(必须不含状态栏,默认ios7中控制器是包括了状态栏的)BeyondViewController *beyondVC = (BeyondViewController *)self.view.window.rootViewController;// 背景图片 总的大小CGSize size = beyondVC.view.frame.size;// 开启上下文,使用參数之后,截出来的是原图(YES  0.0 质量高)UIGraphicsBeginImageContextWithOptions(size, YES, 0.0);// 要裁剪的矩形范围CGRect rect = CGRectMake(0, -20.8, size.width, size.height + 20 );//注:iOS7以后renderInContext:由drawViewHierarchyInRect:afterScreenUpdates:替代[beyondVC.view drawViewHierarchyInRect:rect  afterScreenUpdates:NO];// 从上下文中,取出UIImageUIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext();// 加入截取好的图片到图片数组[_screenshotImgs addObject:snapshot];// 千万记得,结束上下文(移除栈顶的基于当前位图的图形上下文)UIGraphicsEndImageContext();}// 监听手势的方法,仅仅要是有手势就会运行
- (void)panGestureRec:(UIPanGestureRecognizer *)panGestureRec
{// 假设当前显示的控制器已经是根控制器了,不须要做不论什么切换动画,直接返回if(self.topViewController == self.viewControllers[0]) return;// 推断pan手势的各个阶段switch (panGestureRec.state) {case UIGestureRecognizerStateBegan:// 開始拖拽阶段[self dragBegin];break;case UIGestureRecognizerStateEnded:// 结束拖拽阶段[self dragEnd];break;default:// 正在拖拽阶段[self dragging:panGestureRec];break;}
}#pragma mark 開始拖动,加入图片和遮罩
- (void)dragBegin
{// 重点,每次開始Pan手势时,都要加入截图imageview 和 遮盖cover到window中[self.view.window insertSubview:_screenshotImgView atIndex:0];[self.view.window insertSubview:_coverView aboveSubview:_screenshotImgView];// 而且,让imgView显示截图数组中的最后(最新)一张截图_screenshotImgView.image = [_screenshotImgs lastObject];
}// 默认的将要进行缩放的截图的初始比例
#define kDefaultScale 0.6
// 默认的将要变透明的遮罩的初始透明度(全黑)
#define kDefaultAlpha 1.0// 当拖动的距离,占了屏幕的总宽度的3/4时, 就让imageview全然显示。遮盖全然消失
#define kTargetTranslateScale 0.75
#pragma mark 正在拖动,动画效果的精髓,进行缩放和透明度变化
- (void)dragging:(UIPanGestureRecognizer *)pan
{// 得到手指拖动的位移CGFloat offsetX = [pan translationInView:self.view].x;// 仅仅同意往右边拖,禁止向左拖if (offsetX < 0) offsetX = 0;// 让整个导航的view都平移     self.view.transform = CGAffineTransformMakeTranslation(offsetX, 0);// 计算眼下手指拖动位移占屏幕总的宽度的比例,当这个比例达到3/4时, 就让imageview全然显示。遮盖全然消失double currentTranslateScaleX = offsetX/self.view.frame.size.width;// 让imageview缩放,默认的比例+(当前平移比例/目标平移比例)*(1-默认的比例)double scale = kDefaultScale + (currentTranslateScaleX/kTargetTranslateScale) * (1 - kDefaultScale);// 已经达到原始大小了,就能够了,不用放得更大了if (scale > 1) scale = 1;_screenshotImgView.transform = CGAffineTransformMakeScale(scale, scale);// 让遮盖透明度改变,直到减为0,让遮罩全然透明,默认的比例-(当前平移比例/目标平移比例)*默认的比例double alpha = kDefaultAlpha - (currentTranslateScaleX/kTargetTranslateScale) * kDefaultAlpha;_coverView.alpha = alpha;
}#pragma mark 结束拖动,推断结束时拖动的距离作对应的处理,并将图片和遮罩从父控件上移除
- (void)dragEnd
{// 取出挪动的距离CGFloat translateX = self.view.transform.tx;// 取出宽度CGFloat width = self.view.frame.size.width;if (translateX <= width * 0.5) {// 假设手指移动的距离还不到屏幕的一半,往左边挪 (弹回)[UIView animateWithDuration:0.3 animations:^{// 重要~~让被右移的view弹回归位,仅仅要清空transform就可以办到self.view.transform = CGAffineTransformIdentity;// 让imageView大小恢复默认的scale_screenshotImgView.transform = CGAffineTransformMakeScale(kDefaultScale, kDefaultScale);// 让遮盖的透明度恢复默认的alpha 1.0_coverView.alpha = kDefaultAlpha;} completion:^(BOOL finished) {// 重要,动画完毕之后,每次都要记得 移除两个view,下次開始拖动时,再加入进来[_screenshotImgView removeFromSuperview];[_coverView removeFromSuperview];}];} else {// 假设手指移动的距离还超过了屏幕的一半,往右边挪[UIView animateWithDuration:0.3 animations:^{// 让被右移的view全然挪到屏幕的最右边,结束之后,还要记得清空view的transformself.view.transform = CGAffineTransformMakeTranslation(width, 0);// 让imageView缩放置为1_screenshotImgView.transform = CGAffineTransformMakeScale(1, 1);// 让遮盖alpha变为0,变得全然透明_coverView.alpha = 0;} completion:^(BOOL finished) {// 重要~~让被右移的view全然挪到屏幕的最右边,结束之后,还要记得清空view的transform,不然下次再次開始drag时会出问题,由于view的transform没有归零self.view.transform = CGAffineTransformIdentity;// 移除两个view,下次開始拖动时,再加回来[_screenshotImgView removeFromSuperview];[_coverView removeFromSuperview];// 运行正常的Pop操作:移除栈顶控制器,让真正的前一个控制器成为导航控制器的栈顶控制器[self popViewControllerAnimated:NO];// 重要~记得这时候,能够移除截图数组里面最后一张无用的截图了[_screenshotImgs removeLastObject];}];}
}
@end

转载于:https://www.cnblogs.com/jzssuanfa/p/6844507.html

iOS_20_微博自己定义可动画切换的导航控制器相关推荐

  1. Activity左边滑出,右边滑入的动画切换

    Activity左边滑出,右边滑入的动画切换 转载请注明出处:http://blog.csdn.net/u012301841/article/details/46920809 大家都知道Android ...

  2. Activity动画切换3种方案

    小编这里介绍三种Activity间的动画切换方式: 1.  overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim); 2.  The ...

  3. Android SmartTabLayout worm蠕虫蠕动/普通平整动画切换动画属性

     Android SmartTabLayout worm蠕虫蠕动/普通平整动画切换动画属性 Android SmartTabLayout在github上的开源项目主页:https://github ...

  4. android 左进动画,Activity左边滑出,右边滑入的动画切换

    Activity左边滑出,右边滑入的动画切换 大家都知道Android系统默认Activity间的动画切换效果为:左边滑出.右边滑入.按返回键的动画切换效果为:左边滑入,右边滑出.可是如今的手机制造商 ...

  5. 4款基于jquery的列表图标动画切换特效

    网页中列表图标随处可见,特别是移动网页上,基本上的导航都采用了列表图标.今天给大家分享4款基于juqery的列表图标和关闭图标的动画切换特效.喜欢的网友赶紧收藏吧. 在线预览   源码下载 实现的代码 ...

  6. 任务的定义、任务切换的原理及实现

    文章目录 1 任务的定义 2 任务切换的原理 3 任务切换的实现 3.1 设计目标 3.2 设计实现 3.3 代码实现 3.4 PendSV_Handler的另一种实现 1 任务的定义 任务的外观:一 ...

  7. 用动画切换按钮的状态

    用动画切换按钮的状态 效果 源码 https://github.com/YouXianMing/UI-Component-Collection // // BaseControl.h // BaseB ...

  8. 猫猫学iOS 之微博项目实战(2)微博主框架-自己定义导航控制器NavigationController

    猫猫分享.必须精品 原创文章,欢迎转载.转载请注明:翟乃玉的博客 地址:http://blog.csdn.net/u013357243? viewmode=contents 一:加入导航控制器 上一篇 ...

  9. html做app的切换效果,Vue-router结合transition实现app动画切换效果实例分享

    本文主要为大家带来一篇Vue-router结合transition实现app前进后退动画切换效果的实例.小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧,希望能帮助到大家. ...

最新文章

  1. 第五期 RHCE远程班 12月1日开课(周末班)
  2. 12.JDK1.8 JVM运行时数据区域概览、各区域介绍、程序计数器、Java虚拟机栈、本地方法栈、堆、堆空间内存分配(默认情况下)、字符串常量池、元数据区、jvm参数配置
  3. 几十行python代码构建一个前后端分离的目标检测演示网站,代码开源
  4. Windows XP远程桌面控制图文教程
  5. 【Matlab学习笔记】保存图片(待续)
  6. mysql记录的增删改查、单表查询
  7. 凝胶渗透色谱的基本概念(一)
  8. “但问耕耘,莫问收获”才有机会“碰运气”——新书《成功与运气:好运和精英社会的神话》解读
  9. 突然有感而发,发一个自己杜撰的小寓言
  10. 高通平台修改msm8916_defconfig
  11. Altium Designer PCB板框扩大
  12. css之@media网页适配
  13. 【Books系列】之第三本书:《新物种爆炸》读书笔记
  14. python练习题---矩阵求和
  15. UDP的主要特点、首部格式及功能
  16. 软件分发linux,软件分发工具 | 自动化软件分发 - ManageEngine Desktop Central
  17. dbms_xplan
  18. 基于K均值算法的鸢尾花聚类实验(Sklearn实现)
  19. Le wagon编程训练营2021数据科学就业市场最全分析
  20. 微信音响服务器断是信号不好吗,HIFIDIY论坛-有人在微信上转发的一篇文章- 音响发烧大多并不是因为喜欢音乐 - Powered by Discuz!...

热门文章

  1. 黑马程序员Linux系统开发视频之gdb调试方法
  2. DOS环境下支持的最大内存是多少?
  3. 要继续使用 App Engine 标准应用,您必须在 2021 年 1 月 31 日之前添加付款信息。
  4. 写给想转行机器学习深度学习的同学
  5. java facade dao_java – 在Facade模式中放置用于创建namedQuer...
  6. au vst插件_失真效果音频插件
  7. form select multiple 某个字段是数组_你知道什么是Select函数吗?
  8. oracle的存储过程 替换,为什么在存储过程中,变量替换无法使用索引?
  9. php设置背景为透明,css如何设置背景颜色透明?css设置背景颜色透明度的两种方法介绍...
  10. java8 stream中的惰性求值