介绍:在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. mycncart 前台代码跟踪

    1.进入根目录的入口文件,index.php require_once(DIR_SYSTEM . 'startup.php');//最为重要的一步 start('catalog');//执行了这个方法 ...

  2. [Jsoi2011]柠檬

    Description Flute 很喜欢柠檬.它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬.贝壳一共有 N (1 ≤ N ≤ 100,000) 只,按顺序串在树枝上.为了方便,我们从 ...

  3. 【python】if __name__ == '__main__'

    转载自:http://www.cnblogs.com/xuxm2007/archive/2010/08/04/1792463.html 当你打开一个.py文件时,经常会在代码的最下面看到if __na ...

  4. Freemarker的页面和JS遍历后台传入的Map

    后端传到前端的Map Freemarker页面遍历Map: JS遍历Map:

  5. zabbix通过jvm监控tomcat

    说明:zabbix是通过jvm工具监控tomcat,zabbix server通过连接jvm代理服务器获取tomcat的各种参数 zabbix server:192.168.1.31 tomcat服务 ...

  6. 捕获浏览器的前进、后退事件 window.onhashchange 并区别于点击链接

    <html> <head> <meta http-equiv="content-type" content="text/html;chars ...

  7. 0818JavaWeb基础

    Java Web基础 JSP JSP --- Java Server Page        在服务器上运行的页面 动态网页(JSP网页)        与后台有数据交换的网页             ...

  8. Linux命令之which

    which [选项] [命令] 将命令的完整路径写入标准输出.具体是在环境变量PATH设置的目录里查找符合条件的文件,而环境变量PATH中保存了查找命令时需要遍历的目录. (1).选项 -v,-V,- ...

  9. 线程间操作无效: 从不是创建控件“textBox2”的线程访问它

    如何:对 Windows 窗体控件进行线程安全调用 线程间操作无效: 从不是创建控件的线程访问它的三种方法 如果使用多线程处理来提高 Windows 窗体应用程序的性能,则你必须确保以线程安全的方式调 ...

  10. 在intellij idea 中进行android 单元测试

    本次用来测试的代码是sqlite进行数据操作. ######右键选择要进行单元测试的应用 #############弹出选择框,选择Android>Test Module>Next ### ...