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實現側滑效果失效的問題