在程序中,总会设置“返回”按钮,但不可能在每一个控制器中都去设置一次“返回”按钮,那如何设置全局的“返回”按钮呢?

首先自定义一个导航控制器,在tabBarController中添加子控制器时,使用这个自定义的导航控制器,所以在这个导航控制器中重写push方法设置“返回”按钮就可以了。

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
// 如果是根控制器,则不需要添加“返回”按钮
if (self.childViewControllers.count > ) {
viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem wx_itemBackWithTarget:self action:@selector(backClick)];
viewController.hidesBottomBarWhenPushed = YES;
}
[super pushViewController:viewController animated:animated];
}

需要注意的是,如果自己设置了“返回”按钮,那么系统的边缘滑动返回功能就失效了,这是为什么呢?

边缘滑动返回功能失效的原因:

1>分析:边缘滑动功能属于手势操作,在UINavigationController中找到手势属性,打印输出看手势是否被清空

@property(nullable, nonatomic, readonly) UIGestureRecognizer *interactivePopGestureRecognizer NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (self.childViewControllers.count > ) {
viewController.navigationItem.leftBarButtonItem = [UIBarButtonItem wx_itemBackWithTarget:self action:@selector(backClick)];
viewController.hidesBottomBarWhenPushed = YES; // 输出手势
WXLog(@"%@",self.interactivePopGestureRecognizer);
}
[super pushViewController:viewController animated:animated];
}

输出结果:

-- ::39.874 caravan-alter[:] <UIScreenEdgePanGestureRecognizer: 0x7f80c9e80860; state = Possible; delaysTouchesBegan = YES; view = <UILayoutContainerView 0x7f80c9e53d50>; target= <(action=handleNavigationTransition:, target=<_UINavigationInteractiveTransition 0x7f80c9ea1ad0>)>>

结论:手势并没有被清空,所以排除手势被清空的可能。

2>分析:手势代理做了一些事情,导致手势失效

在viewDidLoad中输入以下代码:

self.interactivePopGestureRecognizer.delegate = nil;

结论:将代理清空时,边缘滑动手势恢复,但出现的问题是,如果在根控制器继续使用边缘滑动手势操作,那么在下一次push的时候会出现程序假死的情况。将代理清空

解决:将代理设置为self,判断手势是否恢复,只需要判断在根控制器下,不需要滑动手势即可。

// 两个方法都可以,二选一即可
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
return self.childViewControllers.count > ;
} - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
return self.childViewControllers.count > ;
}

为了给用户更好的体验效果,可以给程序添加全屏滑动效果。

实现:根据打印输出边缘滑动手势,不难发现一些东西:

  UIScreenEdgePanGestureRecognizer:屏幕边缘手势

  target=<_UINavigationInteractiveTransition 0x7f80c9ea1ad0>

  action=handleNavigationTransition:

有了这些信息,只需要找到_UINavigationInteractiveTransition这个类就可以了,当设置手势代理之前打印输出self.interactivePopGestureRecognizer.delegate,可以发现手势代理就是这个类,实现代码:

- (void)viewDidLoad {
[super viewDidLoad]; UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self.interactivePopGestureRecognizer.delegate action:@selector(handleNavigationTransition:)];
// 判断手势什么时候触发
pan.delegate = self;
// 添加手势
[self.view addGestureRecognizer:pan]; // 添加了全屏手势,边缘手势就没什么用了
// self.interactivePopGestureRecognizer.delegate = self;
}

全屏手势就这样实现了!

iOS项目之“返回”手势操作相关的更多相关文章

  1. iOS项目之WKWebView替换UIWebView相关

    在网上已经有了许多关于UIWebView替换为WKWebView的文章,所以在这里就不在多说替换的细节了,不会的可以在网上搜搜. 下面是我在项目中遇到的问题: 问题一:在UIWebView中,网页显示 ...

  2. iOS中“返回”操作相关

    在程序中,总会设置“返回”按钮,但不可能在每一个控制器中都去设置一次“返回”按钮,那如何设置全局的“返回”按钮呢? 首先自定义一个导航控制器,在tabBarController中添加子控制器时,使用这 ...

  3. IOS各种手势操作实例

    先看下效果 手势相关的介绍 IOS中手势操作一般是 UIGestureRecognizer 类的几个手势子类去实现,一般我们用到的手势就这么5种: 1.点击  UITapGestureRecogniz ...

  4. iOS学习—— UINavigationController的返回按钮与侧滑返回手势的研究

    侧滑返回手势是从iOS7开始增加的一个返回操作,经历了两年时间估计iPhone用户大部分都已经忽略了屏幕左上角那个碍眼的back按钮了.之前在网上搜过有关侧滑手势的技术博客,发现大多比较散乱,甚至有很 ...

  5. react-native 手势操作和 react-naviagation 组件的手势返回功能的冲突解决

    上篇我们说到过在react-native触摸及手势事件 那么我在项目中遇到的问题是在react-navigation中的子页面,希望保留在ios中的效果:从左侧往右侧滑动为退出该页面. 但是希望我在滑 ...

  6. iOS 如何设置导航的滑动返回手势, 和系统饿一样

    iOS 7 滑动返回那些事儿 2014/05/17 Wei .entry-meta .entry-header 在智能机越来越普及,屏幕越做越大的当下,滑动返回手势已经成为了一个应用的标配功能,甚至可 ...

  7. iOS 手势操作:拖动、捏合、旋转、点按、长按、轻扫、自定义

    1.UIGestureRecognizer 介绍 手势识别在 iOS 中非常重要,他极大地提高了移动设备的使用便捷性. iOS 系统在 3.2 以后,他提供了一些常用的手势(UIGestureReco ...

  8. iOS开发之自定义导航栏返回按钮右滑返回手势失效的解决

    我相信针对每一个iOS开发者来说~除了根视图控制器外~所有的界面通过导航栏push过去的界面都是可以通过右滑来返回上一个界面~其实~在很多应用和APP中~用户已经习惯了这个功能~然而~作为开发者的我们 ...

  9. grails项目中(DB的相关操作)

    grails项目中(DB的相关操作) save:保存Domain对象的数据到对应的库表中(可能是insert也可能是update) findBy: 动态方法,查找并返回第一条记录,方法名可以变化 eg ...

随机推荐

  1. VUE设置浏览器icon图标

    一.将[logo.png]格式图片转换为[logo.bmp]格式 ps打开图片- 存储为 BMP格式 保存好的[logo.bmp] 格式的图片重命名为[logo.ico] 二.将[logo.ico]图 ...

  2. eclipse 优化

    1.取消验证 windows–>perferences–>validation 把 除了manual 下面的全部点掉,build下只留 classpath dependency Valid ...

  3. pymysql下报错:numpy.float64 object has no attribute 'translate' 可能是pandas版本的问题

    pymysql下报错:numpy.float64 object has no attribute 'translate'.定位到db.merge函数中,dataframe中浮点型元素的类型为numpy ...

  4. 多线程——继承Thread类实现一个多线程

    继承Thread类实现一个多线程 Thread类部分源码: package java.lang; //该类实现了Runnable接口 public class Thread implements Ru ...

  5. APP网络优化篇

    Android Addresses are cached for 600 seconds (10 minutes) by default. Failed lookups are cached for ...

  6. pyCharm编辑器激活使用

    1.打开激活窗口 2.选择 Activate new license with License server (用license server 激活) 3.在 License sever addres ...

  7. 部署一个不依赖tomcat容器的应用

    一个task项目,应用里边都是一些定时任务.我和新入职的高开商定程序部署不依赖于tomcat. 计划赶不上变化,任务开发完成还没等上线呢,哥们要离职了.工作交接时大概说了一下上线怎么部署. 结果呢,当 ...

  8. JDK源码调试常见错误。

    1.删除不需要的代码,即swing相关的代码 2.执行命令时要将前提环境进入文件夹如下: 起初没有完全执行第一条,因为网上说可以根据需要选择相关的代码,于是就没有删除,以后第一次模仿网上的例子的时候要 ...

  9. sourceInsight工具移除不掉项目 source Insight Add and Remove Project Files

    问题描述: sourceInsight创建的项目,有时候会遇到Remove Project 报错,移除不成功的情况. 解决办法: 进入到sourceinsight的安装目录.删除掉保存的工程文件信息即 ...

  10. hiho #1014 : Trie树(模板)

    Trie树 [题目链接]Trie树 &题意: 输入 输入的第一行为一个正整数n,表示词典的大小,其后n行,每一行一个单词(不保证是英文单词,也有可能是火星文单词哦),单词由不超过10个的小写英 ...