欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

右滑返回手势和UIScrollView中手势冲突的解决方法

程序员文章站 2024-02-15 19:38:22
项目中遇到一个页面中是以一个scrollview横向tab展示两个不同功能的显示,譬如消息和公告功能,但是由于滑动返回手势和scrollview的滑动返回手势冲突了,导致页...

项目中遇到一个页面中是以一个scrollview横向tab展示两个不同功能的显示,譬如消息和公告功能,但是由于滑动返回手势和scrollview的滑动返回手势冲突了,导致页面不再能够滑动返回。类似的还有图片浏览功能也出现过。

ios系统中,滑动返回手势,其实是一个uipangesturerecognizer,系统默认的操作是只有滑动屏幕的左边的某个位置,uipangesturerecognizer才会起作用。uiscrollview的滑动手势也是uipangesturerecognizer。那在侧边滑动时,让uiscrollview的不响应事件就ok了嘛,首先想到了继承uiscrollview 重写下面的方法,让滑动侧边时scrollview不响应事件,根据响应者链,事件最终会传递给下方的滑动手势。

- (uiview *)hittest:(cgpoint)point withevent:(uievent *)event   {
   if (point.x < location.x) { // location.x为系统的某个点的x
     return nil;
   } else {
     return [super hittest:point withevent:event];
   }
}

但是,这样有个问题,就是在一个页面不同tab时,也需要滑动切换,滑动返回。

由于scrollview的滑动手势拦截了事件,那我重写scrollview中pangesturerecognizer的代理方法,让它不拦截就好了嘛。于是继承uiscrollview,重写下面的方法。

- (bool)gesturerecognizer:(uigesturerecognizer *)gesturerecognizer shouldrecognizesimultaneouslywithgesturerecognizer:(uigesturerecognizer *)othergesturerecognizer {

    if ([self panback:gesturerecognizer]) {
       return yes;
    }
    return no;

 }


- (bool)panback:(uigesturerecognizer *)gesturerecognizer {

  if (gesturerecognizer == self.pangesturerecognizer) {
     uipangesturerecognizer *pan = (uipangesturerecognizer *)gesturerecognizer;
     cgpoint point = [pan translationinview:self];
     uigesturerecognizerstate state = gesturerecognizer.state;
     if (uigesturerecognizerstatebegan == state || uigesturerecognizerstatepossible == state) {
       cgpoint location = [gesturerecognizer locationinview:self];
       if (point.x > 0 && location.x < “这个自己设定" && self.contentoffset.x <= 0) {
          return yes;
       }
     }
   }
   return no;

}

需要侧边滑动时 panback 返回yes,这时候,我让scrollview的手势和页面的滑动返回手势共存,scrollview不拦截手势,那不就可以滑动返回了吗。好了,测试一下,可以滑动返回,但是滑动返回时,为什么scrollview也跟着在滑动呢,太影响美观了,看来还需要另外的办法,我又回到了第一种办法时的想法,让scrollview切换的时候相应pangesture,滑动返回的时候不响应,那重写scrollview中的另外一个pangesturerecognizer的代理方法。

- (bool)gesturerecognizershouldbegin:(uigesturerecognizer *)gesturerecognizer {

  if ([self panback:gesturerecognizer]) {
    return no;
  }
  return yes;

}

第二种方法:

 -(bool)gesturerecognizer:(uigesturerecognizer *)gesturerecognizer shouldrecognizesimultaneouslywithgesturerecognizer:(uigesturerecognizer *)othergesturerecognizer 
 { 
   // 首先判断othergesturerecognizer是不是系统pop手势 
   if ([othergesturerecognizer.view iskindofclass:nsclassfromstring(@"uilayoutcontainerview")]) { 
     // 再判断系统手势的state是began还是fail,同时判断scrollview的位置是不是正好在最左边 
     if (othergesturerecognizer.state == uigesturerecognizerstatebegan && self.contentoffset.x == 0) { 
       return yes; 
     } 
   } 

   return no; 
}

以上的代码都是在一个自定义的uiscrollview上的,重写上面的方法即可。然后让横向滚动的scrollview继承这个自定义uiscrollview就ok了。

原理:
scrollview的pan手势会让系统的pan手势失效,所以我们只需要在系统手势失效且scrollview的位置在初始位置的时候让两个手势同时启用就可以了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。