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

首先自定义一个导航控制器,在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:文件操作相关(18-03-23更)

    0.iOS文件系统 1.工程内文件 2.文件夹管理 3.文件操作 4.NSCache 附录: 1.沙盒文件夹.文件大小 2.清除沙盒 Library / Cache 下所有数据 3.测试plist 0 ...

  2. iOS中XML的相关知识

    1.什么是XML “当 XML(扩展标记语言)于 1998 年 2 月被引入软件工业界时,它给整个行业带来了一场风暴.有史以来第一次,这个世界拥有了一种用来结构化文档和数据的通用且适应性强的格式,它不 ...

  3. iOS中sqlite3操作

    声明:下面命令我没有所有使用过, 仅用于收藏, 欢迎大家指出当中的错误 'SELECT  count(*)   FROM sqlite_master WHERE type="table&qu ...

  4. Django中数据库操作相关的错误

    问题:字段修改属性发生错误 1> >python manage.py makemigrations You are trying to add a non-nullable field ' ...

  5. IOS中字符串操作

    1.比较大小 - (NSComparisonResult)compare:(NSString *)string; 返回值NSComparisonResult有3种情况: NSOrderedAscend ...

  6. iOS 中 延迟操作四种方式

    本文列举了四种延时执行某函数的方法及其一些区别.假如延时1秒时间执行下面的方法. - (void)delayMethod { NSLog(@"execute"); } 1.perf ...

  7. IOS各种手势操作实例

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

  8. iOS开发中获取WiFi相关信息

    iOS 开发中难免会遇到很多与网络方面的判断,这里做个汇总,大多可能是与WiFi相关的. 1.Ping域名.Ping某IP 有 时候可能会遇到ping 某个域名或者ip通不通,再做下一步操作.这里的p ...

  9. 关于ios中的文本操作-简介

    来源:About Text Handling in iOS 官方文档 iOS平台为我们提供了许多在app中展示文本和让用户编辑文本的方式.同时,它也允许你在app视图中展示格式化的文本和网页内容.你可 ...

随机推荐

  1. flexbox 的相关属性的运用

    若是用 JS 动态的添加 html 元素到有 flexbox 属性的元素上,那么渲染的时候 可能会有问题. CSS 代码如下: .display-flex { /* OLD: Safari, iOS, ...

  2. virtualbox ubuntu 网络连接 以及 连接 secureCRT

    参考http://luowei828.blog.163.com/blog/static/31031204201263125415257/ 用Host-Only 方案      ip: VirtualB ...

  3. myBatis,Spring,SpringMVC三大框架ssm整合模板

    整合步骤 创建web工程 导入整合所需的所有jar包 编写各层需要的配置文件 1) mybatis的全局配置文件 <configuration>    <!-- 批量别名的设置 -- ...

  4. 全是套路——BFS

    #include <iostream> #include <vector> #include <string> #include <vector> #i ...

  5. 介绍开源的.net通信框架NetworkComms框架 源码分析

    原文网址: http://www.cnblogs.com/csdev Networkcomms 是一款C# 语言编写的TCP/UDP通信框架  作者是英国人  以前是收费的 售价249英镑 我曾经花了 ...

  6. hdu 3579 Hello Kiki (中国剩余定理)

    Hello Kiki Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  7. sqlalchemy 大全

    SQLAchemy SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行S ...

  8. 第一章 删掉centos原有的openjdk并安装sun jdk

    一.卸载原有openjdk rpm -qa | grep java 之后,将展示出来的全部卸载掉,我这里是5个 rpm -e --nodeps java-1.7.0-openjdk-1.7.0.111 ...

  9. 如何在string.Format()方法中输出大括号

    在string.Format参数中,大括号{}是有特殊意义的符号,但是如果我们希望最终的结果中包含大括号({}),那么我们需要怎么做呢?是”\{”吗?很遗憾,运行时,会给你一个Exception的!正 ...

  10. Redis与Memcached的区别

    传统MySQL+ Memcached架构遇到的问题 实际MySQL是适合进行海量数据存储的,通过Memcached将热点数据加载到cache,加速访问,很多公司都曾经使用过这样的架构,但随着业务数据量 ...