原文:http://blog.sina.com.cn/s/blog_65c178a80102v0f4.html


前言:
ios7开始 苹果增加了页面 右滑返回的效果;具体的是以UINavigationController为容器的ViewController间右滑切换页面。
代码里的设置是:

self.navigationController.interactivePopGestureRecognizer.enabled = YES;(default is YES)

可以看到苹果给navigationController添加了一个手势(具体为UIScreenEdgePanGestureRecognizer(边缘手势,同样是ios7以后才有的)),就是利用这个手势实现的 ios7的侧滑返回。

问题1:
然而事情并非我们想的那么简单。
1.当我们用系统的UINavigationController,并且也是利用系统的navigateBar的时候,是完全没有问题的
2.但是当我们没有用系统的navigateBar或者自定义了返回按钮的时候,这个时候 右滑返回是失效的。

解决(问题1)办法:
对于这种失效的情况,考虑到interactivePopGestureRecognizer也有delegate属性,替换默认的self.navigationController.interactivePopGestureRecognizer.delegate来配置右滑返回的表现也是可行的。

我们可以在NavigationController中设置一下:
self.navigationController.interactivePopGestureRecognizer.delegate =(id)self

问题2
但是出现很多问题,比如说在rootViewController的时候这个手势也可以响应,导致整个程序页面不响应;push了多层后,快速的触发两次手势,也会错乱

解决(问题2)办法:

@interface NavRootViewController : UINavigationController
@property(nonatomic,weak) UIViewController* currentShowVC;
@end
@implementation NavRootViewController
-(id)initWithRootViewController:(UIViewController *)rootViewController
{
NavRootViewController* nvc = [super initWithRootViewController:rootViewController];
self.interactivePopGestureRecognizer.delegate = self;
nvc.delegate = self;
return nvc;
}
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
}
-(void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
if (navigationController.viewControllers.count == 1)
self.currentShowVC = Nil;
else
self.currentShowVC = viewController;
}
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer == self.interactivePopGestureRecognizer) {
return (self.currentShowVC == self.topViewController); //the most important
}
return YES;
}
@end
借鉴了别人的方法:具体是通过 获取当前pushView栈里的当前显示的VC,根据这个VC来决定 是否开启手势(如果currentShowVC 是当前显示的,则开启手势;如果 currentShowVC为nil,则代表在主页面,关闭手势)
注:
当时试了一种方法 就是滑动的时候来回设置 interactivePopGestureRecognizer的delegate;发现 会有crash,原因就是 因为 我把 当前显示的VC设置为了这个手势的delegate,但当这个VC消失的时候,这个delegate便被释放了,导致crash

至此,觉得ios7上的右滑返回大功告成了,心里正happy,妈蛋,发现了一个可耻的bug:
UIScrollView 上 右滑返回的手势失灵了,靠!!!!!!

问题三:

UIScrollView上手势失灵:
经研究,发现是UIScrollView上已经添加了 panGestureRecognizer(滑动)手势

解决(问题三)办法:
参考:http://www.cnblogs.com/lexingyu/p/3702742.html

【解决方案】

苹果以UIGestureRecognizerDelegate的形式,支持多个UIGestureRecognizer共存。其中的一个方法是:

1 // called when the recognition of one of gestureRecognizer or otherGestureRecognizer would be blocked by the other 2 // return YES to allow both to recognize simultaneously. the default implementation returns NO (by default no two gestures can be recognized simultaneously) 3 // 4 // note: returning YES is guaranteed to allow simultaneous recognition. returning NO is not guaranteed to prevent simultaneous recognition, as the other gesture's delegate may return YES 5 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;

一句话总结就是此方法返回YES时,手势事件会一直往下传递,不论当前层次是否对该事件进行响应。

@implementation UIScrollView (AllowPanGestureEventPass)

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]
        && [otherGestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]])
    {
        return YES;
    }
    else
    {
        return  NO;
    }
}

事实上,对UIGestureRecognizer来说,它们对事件的接收顺序和对事件的响应是可以分开设置的,即存在接收链和响应链。接收链如上文所述,和UIView绑定,由UIView的层次决定接收顺序。

而响应链在apple君的定义下,逻辑出奇的简单,只有一个方法可以设置多个gestureRecognizer的响应关系:

// create a relationship with another gesture recognizer that will prevent this gesture's actions from being called until otherGestureRecognizer transitions to UIGestureRecognizerStateFailed // if otherGestureRecognizer transitions to UIGestureRecognizerStateRecognized or UIGestureRecognizerStateBegan then this recognizer will instead transition to UIGestureRecognizerStateFailed // example usage: a single tap may require a double tap to fail - (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;

每个UIGesturerecognizer都是一个有限状态机,上述方法会在两个gestureRecognizer间建立一个依托于state的依赖关系,当被依赖的gestureRecognizer.state = failed时,另一个gestureRecognizer才能对手势进行响应。

所以,只需要

[_scrollView.panGestureRecognizer requireGestureRecognizerToFail:screenEdgePanGestureRecognizer];

- (UIScreenEdgePanGestureRecognizer *)screenEdgePanGestureRecognizer
{
    UIScreenEdgePanGestureRecognizer *screenEdgePanGestureRecognizer = nil;
    if (self.view.gestureRecognizers.count > 0)
    {
        for (UIGestureRecognizer *recognizer in self.view.gestureRecognizers)
        {
            if ([recognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]])
            {
                screenEdgePanGestureRecognizer = (UIScreenEdgePanGestureRecognizer *)recognizer;
                break;
            }
        }
    }

return screenEdgePanGestureRecognizer;
}

参考:

牛逼 解决了iOS7下滑动返回与ScrollView共存
http://www.cnblogs.com/lexingyu/p/3702742.html

更牛逼  解决了interactivePopGestureRecognizer.delegate 的 释放导致crash的问题
http://www.2cto.com/kf/201401/272886.html


转载于:https://www.cnblogs.com/madordie/p/4357685.html

[搬运] iOS 7 侧滑返回手势使用和错误集相关推荐

  1. iOS 禁用侧滑返回手势要点整理

    项目中可能某些页面返回按钮需要自定义,然后在点击返回按钮时做出某些判断,或者直接弹出到根控制器,这时候需要禁用侧滑返回手势,防止它不走判断的代码直接返回上个界面. 网上找了些资料,大致方法有两种,但要 ...

  2. iOS 禁用侧滑返回手势

    在页面的生命周期设置如下代码 - (void)viewDidAppear:(BOOL)animated{[super viewDidAppear:YES];// 禁用返回手势if ([self.nav ...

  3. 【转】iOS右滑返回手势全解和最佳实施方案

    序言 在ios7以后,苹果推出了手势滑动返回功能,也就是从屏幕左侧向右滑动可返回上一个界面.大大提高了APP在大屏手机和iPad上的操作体验,场景切换更加流畅.做右滑返回手势配置时,可能会遇到的 问题 ...

  4. c2000 pro 固件更新_一加7Pro系统更新新增屏幕侧滑返回手势

    喜大奔粗,使用一加7PRO的小伙伴们有福气了,一加7 Pro第五个固件来了9.5.7.GM21,终于增加了两侧滑动返回,盼星星盼月亮终于盼来了 此次更新内容如下: 系统 优化屏幕触控体验: 优化屏幕显 ...

  5. 氢os 7android 5次 n,一加7 Pro推送氢OS 9.5.7.GM21更新:新增侧滑返回手势

    IT之家7月9日消息 今日,一加7 Pro推送了氢OS 9.5.7.GM21更新,除修复问题与提升系统稳定性外,本次更新还新增屏幕侧滑返回手势,新增人脸解锁屏幕补光功能,更新至2019年6月安卓补丁. ...

  6. Android侧滑返回手机工具,Vivo侧滑返回手势工具app-Vivo手机侧滑手势工具下载v9.2.0.0 安卓版-西西软件下载...

    Vivo手机侧滑手势工具是一款为安卓9的机型用户提供的侧滑手势返回工具,vivo的很多机型现在都没有侧滑返回的手势功能了,这导致一些大屏机型单手操作并不方便,大家可以下载这款Vivo手机侧滑手势工具来 ...

  7. iOS 禁止侧滑返回上个页面

    1.首先把顶部左侧返回按钮隐藏掉 //隐藏返回按钮 self.navigationItem.hidesBackButton = YES; 2.再禁止页面左侧侧滑 //禁止页面左侧滑动返回,注意,如果仅 ...

  8. 06 iOS 关闭侧滑返回

    - (void)viewDidAppear:(BOOL)animated {[super viewDidAppear:animated];// 禁用 iOS7 滑动返回手势if ([self.navi ...

  9. IOS手机侧滑返回与Vue过渡动画冲突

    前端小白一个,最近做的一个Vue项目用到了Vue的过度动画,本来效果挺好的突然发现在IOS手机上项目本身使用的Vue过度动画与IOS侧滑发生冲突,出现了侧滑效果与Vue过度动画重复执行导致页面切换效果 ...

最新文章

  1. Material Design(十一)--CoordinatorLayout和自定义视图
  2. iOS Xcode个人常用插件
  3. python读取文件内容操作_Python 3.6 读取并操作文件内容
  4. python 3.8.2_python-3.8.2-docs-html
  5. verilog语法实例学习(3)
  6. 08. 旋转数组的最小数字(C++版本)
  7. 局域网服务器共享文件夹设置,局域网服务器共享文件访问权限管理方法
  8. VisualSVN Server SVN仓库迁移备份
  9. 一个偶然发现还挺有意思的逻辑题
  10. 利用python创建自定义的股票指数
  11. qt for android 中无法运行和调试应用程序,No Device Found,The adb tool in the Android SDK lists all......
  12. 抢票软件之——py12306使用指南
  13. HP LaserJet 1020打印机显示脱机,脱机使用打印机的勾去不掉
  14. 网络安全工程师年薪百万?到底是干什么的?
  15. 央联众商理财公司,我个人的理财观!
  16. python3《机器学习实战系列》学习笔记----3.2 决策树实战
  17. Docker 入门学习
  18. 计算app用户的留存率
  19. iTerm2 保存登陆密码
  20. c语言上机实验指导西南交通大学,操作系统原理与应用实验指导书-西南交通大学.doc...

热门文章

  1. dnsmasq详解手册
  2. [20180102]11g的V$SORT_USAGE视图.txt
  3. 十三条道德准则-富兰克林
  4. lly dependent on columns in GROUP BY clause; this is incompatible with sql_m
  5. 使用 uiautomator2
  6. C++ 字符串中小写字母转换成大写字母
  7. cvr存储服务器的优势,CVR存储设备的结构与优势分析
  8. DFS(二):骑士游历问题
  9. 函数动态传参详细,作用域和名称空间,global和nonlocal
  10. 洛谷P1402 酒店之王(二分图)