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 ...
随机推荐
- WinDBG调试技巧
参考链接:http://wenku.baidu.com/view/4e58744dcf84b9d528ea7a42.html
- grep命令参数和使用方法
功能说明:查找符合串的条件的文件. 语言 法国:grep [-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C<显示列数>] ...
- 非常不错的android应用开发详解在安卓开发中
我们在苹果开发中,总会看到XCode,Interface Builder,Object-c这如此入耳入随的单词,但往往多数人在认为XCODE看着简单,InterfaceBuilder好似操作, 而Ob ...
- RSA加密解密和读取公钥、私钥
/// <summary> /// RSA加密解密及RSA签名和验证 /// </summary> public class RSADE { ...
- c++里的类型转化
c++里的类型转换种类 在c++里包含4种,static_cast,dynamic_cast,const_cast,reinterpret_cast. 4种类型 reinterpret_cast: 强 ...
- 10 个迅速提升你 Git 水平的提示(转)
最近我们推出了两个教程:熟悉Git的基本功能和 让你在开发团队中熟练的使用Git . 我们所讨论的命令足够一个开发者在Git使用方面游刃有余.在这篇文章中,我们试图探索怎样有效的管理你的时间和充分的使 ...
- iOS 单元測试之XCTest具体解释(一)
原创blog,转载请注明出处 blog.csdn.net/hello_hwc 欢迎关注我的iOS-SDK具体解释专栏 http://blog.csdn.net/column/details/huang ...
- URAL1523(dp+树状数组)
题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=41224#problem/B 分析:可以设dp[i][j]表示以i结尾长度为j的 ...
- 从零開始学android<SeekBar滑动组件.二十二.>
拖动条能够由用户自己进行手工的调节,比如:当用户须要调整播放器音量或者是电影的播放进度时都会使用到拖动条,SeekBar类的定义结构例如以下所看到的: java.lang.Object ↳ an ...
- ServiceProvider实现
ServiceProvider实现揭秘 [总体设计 ] 本系列前面的文章我们主要以编程的角度对ASP.NET Core的依赖注入系统进行了详细的介绍,如果读者朋友们对这些内容具有深刻的理解,我相信你们 ...