设计与Swipe-Delete不冲突的UIPageViewController

2,138 阅读2分钟

问题

当在UIPageViewController中添加UITableView时,如果:

  1. UITableView处在最右边的vc中
  2. UITableView开启了左滑删除(Swipe-Delete)功能

那左滑删除手势和UIPageViewController的滚动手势会有冲突,本文尝试解决该问题,并分享了一个实现源码

对于手势冲突的问题,我会想通过UIGestureDelegate的几个方法来让冲突的手势协同工作。但UIPageViewController并没有提供方法获取或修改滚动手势。于是我的解决方案就是:

自定义UIPageViewController,自己控制手势

自定义UIPageViewController

初步设想用UIScrollView作为展示载体,这样更容易实现左右滑动

由于UIScrollView本身的滚动手势识别器--panGestureRecognizer由其内部控制,我们需要禁用掉。取而代之的是添加自定义的UIPanGestureRecognizer

手势协同

当最右边vc中有UITableView时,当左滑时,通过实现UIGestureRecognizerDelegatefunc gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool方法,使我们自己的panGestureRecognizer不执行。以此来提高UITableView的左滑删除手势优先级

管理Child ViewController

没有自定义container viewcontroller经验的话这一步很容易出错

最初我的设计是,每往UIPageViewController添加一个vc,就将它的view添加到UIScrollView中,UIScrollView一直持有着这些vc

但后来经高人指点--这是不行的,因为

  1. child vc的生命周期可能因此混乱
  2. 原生的UIPageViewController是实时的获取child vc,同一时间只会持有一个vc

基于上面的考虑,我在设计时

  • 模仿原生UIPageViewController,提供setViewController主动设置页面和通过dataSource实时获取下一个、上一个vc的方法
  • 在滚动过程中,通过当前位置等信息,通过dataSource实时获取chiild vc数据
  • 当完成一次child vc的完整展示后,及时释放上一个展示的vc
  • 改用手动方式管理child vc的生命周期,完全模拟原生UIPageViewController

模拟UIPageViewController滚动体验

  • 快速拖拽时,自动跳转到相应页面
  • 在最左、右页面拖拽时的bounce效果

源码