iOS 下如果存在UIScrollerView 使用UIScreenEdgePanGestureRecognizer实现侧滑效果失效的问题

当你在使用UIScreenEdgePanGestureRecognizer手势实现侧滑的时候,如果后期你导航控制器push出的界面中包含UIScrollerView,这个时候你会发现,侧滑效果无法实现了,这个首先你会想到肯定是UIScrollerView,把这个手势给拦截了,执行了UIScrollerView中包含的手势。

问题所在

滑动返回事实上也是由于存在已久的UIScreenEdgePanGestureRecognizer来识别并且相应地,它直接与UINavigationController的view进行了绑定,绑定的方法是写在UINavgationController 的基类中的,正如一下:

UIPanGestureRecongnizer -- bind-- UIScrollerView
UIScreenEdgePanGestureRecognizer --bind-- UINavigationController.view

滑动返回无法触发,说明UIScreenEdgePanGestureRecongnizer并没有接受到手势事件。
根据苹果的<a href= "https://developer.apple.com/library/ios/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/GestureRecognizer_basics/GestureRecognizer_basics.html#//apple_ref/doc/uid/TP40009541-CH2-SW2">官方文档</a>说明 UIGestureRecongnizer 和UIview 是多对一的关系,UIGestureRecognizer 一定要和UIView进行绑定才能发挥作用,因此UIGestureRecongnizer对于屏幕上的手势事件,其接受顺序和UIView的层次结构是一致的,如下关系

UINavgataionController.view -->UIviewController.view -- > UIScrollerView.view -->screen and user'finger 既UIScrollView的panGestureRecognizer
先接受到了手势事件,直接就处理而没有往下传递实际上就是两个手势共存的问题

解决方案

UIGestureRecognizerDelegate 代理方法中包含,支持多个UIGestureRecongnizer共存,其中一个方法是

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,手势事件会一直往下传递,不论当前层次是否对该事件进行响应

看看UIScrollerView的头文件的描述:

1 // Use these accessors to configure the scroll view's built-in gesture recognizers.
2 // Do not change the gestures' delegates or override the getters for these properties.
3 @property(nonatomic, readonly) UIPanGestureRecognizer *panGestureRecognizer NS_AVAILABLE_IOS(5_0);

UIScrollView本身是其panGestureRecognizer的delegate,且apple君明确表明不能修改它的delegate(修改的时候也会有警告)

UIScrollView作为delegate,说明UIScrollView中实现了上文提到的shouldRecognizeSimultaneouslyWithGestureRecognizer方法,返回了NO。创建一个UIScrollView的category,由于category中的同名方法会覆盖原有.m文件中的实现,使得可以自定义手势事件的传递,如下:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{ 
      if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]  && [otherGestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) { 
            return YES; 
      } else  {
            return NO; 
     }
 }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 前言:ios7开始 苹果增加了页面 右滑返回的效果;具体的是以UINavigationController为容器的...
    iPhone阅读 3,775评论 2 3
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,251评论 4 61
  • 魔林初见 一株株高达百尺的古树挺立,似要刺破苍穹,但这里却时不时地飘出一股黑气,给人一种阴森森的感觉。这里就是出名...
    四海WX阅读 513评论 0 0
  • 1.电影原境重现 成才父亲临终时说:“成才,我是在被打的环境中长大,从来没有人爱过我,所以,我也不知道该怎样爱你。...
    张浩永恒之旅阅读 296评论 0 1
  • 入冬啦,街道上彷徨的人少了。 要么是拐进巷子找酒喝,要么是骑着单车裹着大衣,腿还时不时撞到刚买的芹菜。总觉得叮铃铃...
    Deer_Elaine阅读 173评论 0 0