介绍:在iOS中,导航控制器UINavigationController是默认实现左侧边缘侧滑手势出栈的,但是如果当开发者对导航控制器子控制实现自定义leftBaButtonItem时,这个侧滑功能就会失去效果,此时就需要我们在自定义的NavigationController中手动代码去实现了。有的时候为了提高用户体验,会试着进行全屏的侧滑返回,现在这个技术已经普遍应用到app中。下面就来介绍边缘侧滑和全屏侧滑返回。。。。。

第一种方式:实现左侧边缘侧滑返回(系统自带的边缘侧滑,安全可靠)

//
// KJNavgationController.m
//
// Created by mac on 16/2/22.
// Copyright © 2016年 mac. All rights reserved.
// #import "KJNavgationController.h" @interface KJNavgationController ()<UIGestureRecognizerDelegate,UINavigationControllerDelegate> @end @implementation KJNavgationController
-(void)viewDidLoad{
[super viewDidLoad]; __weak KJNavgationController *weakSelf = self; if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
{
self.interactivePopGestureRecognizer.delegate = weakSelf;
self.delegate = weakSelf;
}
} - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
//控制器入栈过程中禁用手势识别
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
self.interactivePopGestureRecognizer.enabled = NO; [super pushViewController:viewController animated:animated];
} #pragma mark UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController
didShowViewController:(UIViewController *)viewController
animated:(BOOL)animate
{
//控制器入栈之后,启用手势识别
if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
self.interactivePopGestureRecognizer.enabled = YES;
} - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if ([self.childViewControllers count] == ) {
return NO;
}
return YES;
} - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
//运行试一试,发现了新问题,手指在滑动的时候,被 pop 的 ViewController 中的 UIScrollView 会跟着一起滚动,这个效果看起来就很怪(知乎日报现在就是这样的效果),而且也不是原始的滑动返回应有的效果,那么就让我们继续用代码来解决吧
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return [gestureRecognizer isKindOfClass:UIScreenEdgePanGestureRecognizer.class];
} @end

优点:实现简单,导航控制器中对全体viewController的侧滑功能可控,系统API绝对安全可靠,无手势冲突

缺点:侧滑范围局限于左侧

适用需求:只需左侧小范围触发侧滑时的首选实现方案。

第二种方式:实现全屏侧滑返回(并不完善的全屏侧滑)

//
// KJNavgationController.m
//
// Created by mac on 16/2/22.
// Copyright © 2016年 mac. All rights reserved.
// #import "KJNavgationController.h" @interface KJNavgationController ()<UIGestureRecognizerDelegate> @end @implementation KJNavgationController -(void)viewDidLoad{
[super viewDidLoad]; // 获取系统自带滑动手势的target对象
id target = self.interactivePopGestureRecognizer.delegate; // 创建全屏滑动手势,调用系统自带滑动手势的target的action方法
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:target action:@selector(handleNavigationTransition:)]; // 设置手势代理,拦截手势触发
pan.delegate = self; // 给导航控制器的view添加全屏滑动手势
[self.view addGestureRecognizer:pan]; // 禁止使用系统自带的滑动手势
self.interactivePopGestureRecognizer.enabled = NO; } // 什么时候调用:每次触发手势之前都会询问下代理,是否触发。
// 作用:拦截手势触发
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
// 注意:只有非根控制器才有滑动返回功能,根控制器没有。
// 判断导航控制器是否只有一个子控制器,如果只有一个子控制器,肯定是根控制器
if (self.childViewControllers.count == ) {
// 表示用户在根控制器界面,就不需要触发滑动手势,
return NO;
}
return YES;
}
@end

优点:最简洁的全屏侧滑实现,导航控制器中对全体viewController的侧滑功能可控

缺点:从右边往左边划动也能触发侧滑操作,有手势冲突,并不完美。且调用官方私有API

另外:正是缺点的所在,和Cell的侧滑删除手势也是有冲突的,也就是说,免不了需要解决手势的冲突。

适用需求:最好不用,毕竟缺点明显。(不过这个实现思路,确实值得称赞!)

第三种方式:(集成最简单、功能最全面):

链接地址下载DEMO,具体详情见github:https://github.com/forkingdog/FDFullscreenPopGesture

使用截图
    

优点:最全面的全屏侧滑实现,集成超简单,全体viewController的侧滑功能可控,不过得在ViewController内部去控制,稍微麻烦一点;另外,百度知道团队在维护该DEMO,功能会越来越完善,花样更多。

缺点:调用官方私有API(不过已有上线作品,不影响上线,缺点可以忽略!)

适用需求:目前最好的全屏侧滑实现方案。

第四种方式:创建swipe扫动手势,实现全屏侧滑返回

- (void)viewDidLoad
{
[super viewDidLoad]; // 添加右滑手势
[self addSwipeRecognizer];
} #pragma mark 添加右滑手势
- (void)addSwipeRecognizer
{
// 初始化手势并添加执行方法
UISwipeGestureRecognizer *swipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(return)]; // 手势方向
swipeRecognizer.direction = UISwipeGestureRecognizerDirectionRight; // 响应的手指数
swipeRecognizer.numberOfTouchesRequired = ; // 添加手势
[[self view] addGestureRecognizer:swipeRecognizer];
} #pragma mark 返回上一级
- (void)return
{
// 最低控制器无需返回
if (self.viewControllers.count <= ) return; // pop返回上一级
[self popToRootViewControllerAnimated:YES];
} //若在控制器之间跳转时需要做一些事情,可在自定义的控制器里添加下面两个方法
#pragma mark push方法
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
// do something you want
...
[super pushViewController:viewController animated:animated];
} #pragma mark pop方法
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
// 比如停止网络请求
... return [super popViewControllerAnimated:animated];
}

优点:用户可以自定义扫动侧滑,没有手势冲突,虽使用官方私有API,但是安全。

缺点:侧滑速度太快,不好控制器,不能中途停止侧滑。

适用需求:根据个人需要决定。

参看链接:

http://www.cocoachina.com/ios/20150811/12897.html

http://www.jianshu.com/p/349636eb3fca

http://www.jianshu.com/p/f83acf1d337b

http://my.oschina.net/cobish/blog/225260

iOS:导航控制器侧滑出栈实现的更多相关文章

  1. 关于ios导航控制器的知识总结

    关于ios导航控制器的知识总结 添加了导航控制器后: 1.一个导航控制器会有一个顶部导航栏navigationbar和一个底部工具栏toolbar,它们是导航控制器navC的属性.且导航栏默认是不隐藏 ...

  2. iOS 导航控制器返回栈中的某一控制器

    #import <UIKit/UIKit.h> @interface AppDelegate : UIResponder <UIApplicationDelegate> @pr ...

  3. iOS导航控制器常用函数与navigationBar常用属性

    导航控制器常用函数触发时机 当视图控制器的View将要出现时触发 - (void)viewWillAppear:(BOOL)animated 当视图控制器的View已经出现时触发 - (void)vi ...

  4. IOS 导航控制器基本使用(UINavigationController代码创建方式)

    ● UINavigationController的使用步骤 ➢ 初始化UINavigationController ➢ 设置UIWindow的rootViewController为UINavigati ...

  5. 关于iOS导航控制器隐藏和显示会出现返回键失效,导航栏标题动画异常

    最近做的demo  bug出现了,我觉得这个bug出现得很经典所以贴出来给大家看看, bug演示就是:点击返回键失效出现如下gif图演示的内容 为啥会出现如此奇葩的bug,系统的返回键居然失效了,尴尬 ...

  6. iOS - 导航控制器

    1.导航控制器 self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; self.window.bac ...

  7. iOS 导航控制器如何随意push和pop 想要在 A push B 后, B 在push 到 D ,然后从 D pop 到 C ,在从 C pop 的A

    这里主要是对导航控制器的viewControllerss这个数组进行操作,因为push操作和pop操作都是根据这个数据去切换控制器或者在这个数组里增加控制器的,所以只要改变这个子控制器数据就能自定义切 ...

  8. IOS开发UI篇—导航控制器属性和基本使用

    IOS开发UI篇—导航控制器属性和基本使用 一.导航控制器的一些属性和基本使用 1.把子控制器添加到导航控制器中的四种方法 (1) 1.创建一个导航控制器 UINavigationController ...

  9. iOS开发——实用技术OC篇&8行代码教你搞定导航控制器全屏滑动返回效果

    8行代码教你搞定导航控制器全屏滑动返回效果 前言 如果自定了导航控制器的自控制器的leftBarButtonItem,可能会引发边缘滑动pop效果的失灵,是由于 self.interactivePop ...

随机推荐

  1. NOIP 2013 day2

    tags: 模拟 贪心 搜索 动态规划 categories: 信息学竞赛 总结 积木大赛 花匠 华容道 积木大赛 Solution 发现如果一段先单调上升然后在单调下降, 那么这一块的代价是最高的减 ...

  2. Mybatis学习—XML映射文件

    总结自 Mybatis官方中文文档 Mapper XML 文件 MyBatis 的真正强大在于它的映射语句,也是它的魔力所在.由于它的异常强大,映射器的 XML 文件就显得相对简单.如果拿它跟具有相同 ...

  3. session和cookie基本操作

    session的作用同cookie一样: 1.在不同页面使用同一数组 2.实现验证码,用户跟踪(个人觉得这个用到的其实还是1中的作用) session相对于cookie更加的安全 先来说一下cooki ...

  4. spring cloud报错解决:java.lang.ClassNotFoundException: com.netflix.servo.monitor.Monitors

    见鬼的事发生了. 在家里电脑上拿样例代码,运行时OK的.但一到公司电脑,用同样的代码,就会报下面的错误 ===================== Caused by: java.lang.Class ...

  5. 使用PuTTY连接树莓派

    这是 meelo 原创的 玩转树莓派 系列文章 PuTTY是一个支持Telnet.SSH协议,实现远程登录的软件.树莓派的官方操作系统Raspbian默认开启了SSH协议进行登录,这样即使没有专门的显 ...

  6. redis三种连接方式

    安装 tar zxvf redis-2.8.9.tar.gz cd redis-2.8.9 #直接make 编译 make #可使用root用户执行`make install`,将可执行文件拷贝到/u ...

  7. C#读取csv文件使用字符串拼接成XML

    phone.csv zhangsan1, zhangsan2, zhangsan3, static void Main(string[] args) { //XML //XML就是一个文件,用来存储数 ...

  8. ORACLE数据库创建动态表

    最近公司一个项目代码里的定时任务无法执行,查验代码良久,奈何代码过于老旧,开发人员换了一茬又一茬,现在都无法理清,故无奈只好到数据库里重新写存过,配置定时任务. 在写存过时,由于检测及安全性能要求,需 ...

  9. Maven实用总结

    使用Maven还是推荐IDEA,以前用eclipse总是喜欢出现乱七八糟的问题,具体错误和解决方案也记不清楚了. 下面总结下IDEA中遇到的问题和解决方法: 与IDEA搭配的相关问题 如何根据模板快速 ...

  10. Linux命令之whereis

    whereis [选项] [文件] (1).选项 -b 只搜索二进制文件 -B <目录> 只在路径下查找二进制文件 -m 只搜索man手册 -M <目录> 只在路径下查找man ...