ios 仿新浪微博 UINavigationController 向左滑动时显示上一个控制器的View.
仿新浪微博 UINavigationController 向左滑动时显示上一个控制器的View.
实现原理,UINavigationController 的 self.view显示时把当前显示的view截图下来,保存到一个数组中。当push一个view时把上一个view的截图放到self.view后面,当self.view向右拖动时显示上一个view。
NavigationController.m
#import "NavigationController.h" @interface NavigationController ()
/** 存放每个控制器的全屏截图 */
@property (nonatomic, strong) NSMutableArray *images;
@property (nonatomic, strong) UIImageView *lastVcView;
@property (nonatomic, strong) UIView *cover;
@end @implementation NavigationController - (UIImageView *)lastVcView
{
if (!_lastVcView) {
UIWindow *window = [UIApplication sharedApplication].keyWindow;
UIImageView *lastVcView = [[UIImageView alloc] init];
lastVcView.frame = window.bounds;
self.lastVcView = lastVcView;
}
return _lastVcView;
} - (UIView *)cover
{
if (!_cover) {
UIWindow *window = [UIApplication sharedApplication].keyWindow;
UIView *cover = [[UIView alloc] init];
cover.backgroundColor = [UIColor blackColor];
cover.frame = window.bounds;
cover.alpha = 0.5;
self.cover = cover;
}
return _cover;
} - (NSMutableArray *)images
{
if (!_images) {
self.images = [[NSMutableArray alloc] init];
}
return _images;
} - (void)viewDidLoad {
[super viewDidLoad]; // 拖拽手势
UIPanGestureRecognizer *recognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(dragging:)];
[self.view addGestureRecognizer:recognizer];
} - (void)dragging:(UIPanGestureRecognizer *)recognizer
{
// 假设仅仅有1个子控制器,停止拖拽
if (self.viewControllers.count <= 1) return; // 在x方向上移动的距离
CGFloat tx = [recognizer translationInView:self.view].x;
if (tx < 0) return; if (recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled) {
// 决定pop还是还原
CGFloat x = self.view.frame.origin.x;
if (x >= self.view.frame.size.width * 0.5) {
[UIView animateWithDuration:0.25 animations:^{
self.view.transform = CGAffineTransformMakeTranslation(self.view.frame.size.width, 0);
} completion:^(BOOL finished) {
[self popViewControllerAnimated:NO];
[self.lastVcView removeFromSuperview];
[self.cover removeFromSuperview];
self.view.transform = CGAffineTransformIdentity;
[self.images removeLastObject];
}];
} else {
[UIView animateWithDuration:0.25 animations:^{
self.view.transform = CGAffineTransformIdentity;
}];
}
} else {
// 移动view
self.view.transform = CGAffineTransformMakeTranslation(tx, 0); UIWindow *window = [UIApplication sharedApplication].keyWindow;
// 加入截图到最后面
self.lastVcView.image = self.images[self.images.count - 2];
[window insertSubview:self.lastVcView atIndex:0];
[window insertSubview:self.cover aboveSubview:self.lastVcView];
}
} /**
* 产生截图
*/
- (void)createScreenShot
{
UIGraphicsBeginImageContextWithOptions(self.view.frame.size, YES, 0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
[self.images addObject:image];
} - (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated]; if (self.images.count > 0) return; [self createScreenShot];
} - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
[super pushViewController:viewController animated:animated]; [self createScreenShot];
} @end
ios 仿新浪微博 UINavigationController 向左滑动时显示上一个控制器的View.的更多相关文章
- Flutter - 添加从左向右滑动,返回上一个页面
很多App比如微信.IT之家等都支持从屏幕左侧向右滑动,来返回上一个页面. 很多iOS上的App也都支持. 那么这个神奇的手势滑动是怎么实现的呢? 其实非常简单,只需要添加一句话即可. platfor ...
- appium 中swipe()方法向左滑动时
应该在UI Automator Viewer中读取到的例如ImageView [180,600][900,1320],如果要左滑,代码中应该是写为driver.swipe(900,1320,180,6 ...
- decltype的参数是左值时,得到一个引用类型
int* a = new int(10); decltype(*a) 得到的是引用类型:int&
- vue 组件来回切换时 记住上一个组件滚动位置(keep-alive)
记住组件滚动状态: 使用场景:从某列表组件进入详情页,在返回的时候需要保留列表组件状态,包括滚动的高度.这个时候需要keep-alive配合. 方法一:如下情况导航在做普遍用法.前提是使用keep-a ...
- VS调试时监视上一个错误代码和错误的文本描述
以前我都是用GetLastError()然后在MSDN里面查错误原因的.现在才知道有很简便的方法: 在Watch窗口选择一行,然后输入$err,hr
- jquery怎么在点击li标签之后添加一个在class,点击下一个li时删除上一个class?
思路:点击当前li元素后是用removeClass()删除所有兄弟元素(使用siblings()获取)的class样式,然后使用addClass()为当前li添加class. 具体演示如下: 1.HT ...
- jquery点击li标签之后在该li标签上添加一个class,点击下一个li时删除上一个li的class
思路:点击当前li元素后是用removeClass()删除所有兄弟元素(使用siblings()获取)的class样式,然后使用addClass()为当前li添加class 具体演示如下: 1.HTM ...
- iOS学习之UINavigationController
一.UINavigationController 1.UINavigationController:导航控制器,是iOS中最常用的多视图控制器之一,用它来管理多个视图控制器.可以称为是管理控 ...
- Android Animation动画实战(一): 从布局动画引入ListView滑动时,每一Item项的显示动画
前言: 之前,我已经写了两篇博文,给大家介绍了Android的基础动画是如何实现的,如果还不清楚的,可以点击查看:Android Animation动画详解(一): 补间动画 及 Android An ...
随机推荐
- hdu2066一个人的旅行
枚举全部相邻城市,作为起点,多次spfa,然后每次在想去的城市中找出spfa后的距离起点最短的花费时间 #include <iostream> #include <cstring&g ...
- 让自己的软件实现拖拽打开文件(使用WM_DROPFILES消息和DragQueryFile函数)
//声明 protected procedure WMDROPFILES(var Msg : TMessage); message WM_DROPFILES; //实现 procedure TForm ...
- Delphi数据类型转换(有几个字符串函数没见过,比如StringToWideChar和WideCharToString)
DateTimeToFileDate 函数 将DELPHI的日期格式转换为DOS的日期格式 DateTimeT ...
- 慎得慌风 656ik67o
http://photo.163.com/q/7634581 http://photo.163.com/q/7634580 http://photo.163.com/q/7634577 http:// ...
- 它们的定义iOS双击Home截图按键开关
<pre name="code" class="objc"><p>双击假设Home,我会去iOS App的switcher页面,这里列出 ...
- Visual Studio 2008中FormatX源代码格式化插件
原地址:http://www.cr173.com/html/15492_1.html 我总是对组里的兄弟代码规范性近乎完美的要求,举个简单的例子: 1. 每个方法必须有注释,方法参数详细说明 2. ...
- XML语法规范
1: 怎样声明一个xml文件 答:由2部分组成 声明部分,声明xml的版本号与编码(版本号仅仅有1.0) <? xml version="1.0" encoding=&quo ...
- RANSAC - 随机采样一致性算法
RANSAC范例的正式描述如下: 首先,要给定: 1一个模型,该模型需要最少n个数据点去实例化它的自由参数: 2一组数据点P,P中包含数据点的数量#(P)大于n. 然后, 从P中随机地选择n个点(组成 ...
- Oracle Client: TNS: Connect timeout ocurred.
1. 检查Oracle Server 的防火墙是否关闭. 2. Client, Server 重启.
- Dan计划:重新定义人生的10000个小时 - 阮一峰的网络日志
Dan计划:重新定义人生的10000个小时 - 阮一峰的网络日志 Dan计划:重新定义人生的10000个小时