UIScreenEdgePanGestureRecognizer *rightEdgeGesture =
[[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self
action:@selector(handleRightEdgeGesture:)];
rightEdgeGesture.edges = UIRectEdgeRight; // 右滑显示
[self.view addGestureRecognizer:rightEdgeGesture];
但是如果存在UIScrollerView 使用UIScreenEdgePanGestureRecognizer实现侧滑效果失效的问题
原因是因为滑动返回事实上也是由于存在已久的UIScreenEdgePanGestureRecognizer来识别并且相应地,它直接与UINavigationController的view进行了绑定,绑定的方法是写在UINavgationController 的基类中的,正如一下:
UIPanGestureRecongnizer -- bind-- UIScrollerView
UIScreenEdgePanGestureRecognizer --bind-- UINavigationController.view
滑动返回无法触发,说明UIScreenEdgePanGestureRecongnizer并没有接受到手势事件。
根据苹果的官方文档说明 UIGestureRecongnizer 和UIview 是多对一的关系,UIGestureRecognizer 一定要和UIView进行绑定才能发挥作用,因此UIGestureRecongnizer对于屏幕上的手势事件,其接受顺序和UIView的层次结构是一致的,如下关系
UINavgataionController.view -->UIviewController.view -- > UIScrollerView.view -->screen and user'finger 既UIScrollView的panGestureRecognizer
先接受到了手势事件,直接就处理而没有往下传递实际上就是两个手势共存的问题
触发手势的时候因为scrollview在上边,所以没有往下传递
解决方案
UIGestureRecognizerDelegate 代理方法中包含,支持多个UIGestureRecongnizer共存,其中一个方法是
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
总结就是此方法返回YES,手势事件会一直往下传递,不论当前层次是否对该事件进行响应
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;
}
}
参考:
iOS 下如果存在UIScrollerView 使用UIScreenEdgePanGestureRecognizer实现侧滑效果失效的问题