滚动视图嵌套手势冲突的分析

  1. 滚动视图嵌套
    • UIScrollView 和 UIScrollView
    • UIScrollView 和 UITableView
    • UIScrollView 和 UICollectionView
    • UITableView 和 UITableView
    • UITableView 和 UICollectionView
    • UICollectionView 和 UICollectionView
  2. 表现就是手势事件被子视图响应,父视图不被触发
    • 如果有一个滚动视图为父视图,其子视图时两个tableView,则当在子视图范围内上下滑动时,只会子视图滑动,父视图无反应。
    • 分析
      • 当手势在子视图上滑动时,会产生一个事件,这个事件会被加入到UIApplication循环队列中
      • 事件传递过程中,会找到tableView这个子视图是最合适的响应者
      • tableView本身支持手势,所以这个事件优先交于这个子视图处理,这个子视图处理了这个事件,此响应链事件被取消
      • 所以子视图的父视图不会接收到这个手势事件
  3. 解决方案
    从理论上说,如果子视图处理了这个事件,且这个事件继续按照响应链去传递,则下一个接受者就是父视图,则父视图收到这个事件,且可以处理这个事件。
    • 重写子视图这个类。重新创建一个继承UITableView的类
    • 在.m文件中实现下面这个方法
      /**
       *  支持同时识别手势
       */
      - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
          return YES;
      }
      
    • 然后使用这个类去创建tableView视图,此时在子视图上的滑动手势,父视图也可以接受,并处理
    • 最大的变化就是下面方法可以同时接收到子视图和父视图的滚动事件
      - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
          // do something
      }
      
    • 然后就可以在这里处理子视图和父视图的滚动效果。例如可以做如下处理
      • 当父视图的contentOffset.y为0时,子视图的contentOffset不可变化,表现就是父视图往上滚动,子视图不动
      • 当父视图的contentOffset.y为某个值时,父视图不可滚动,子视图此时可以自由滚动
      • 这就可以很流畅的达到一些界面效果

你可能感兴趣的:(滚动视图嵌套手势冲突的分析)