解決右滑返回手勢和UIScrollView中的手勢衝突

項目中遇到一個頁面中是以一個scrollview橫向Tab展現兩個不一樣功能的顯示,譬如消息和公告功能,可是因爲滑動返回手勢和scrollview的滑動返回手勢衝突了,致使頁面再也不可以滑動返回。相似的還有圖片瀏覽功能也出現過。測試

iOS系統中,滑動返回手勢,實際上是一個UIPanGestureRecognizer,系統默認的操做是隻有滑動屏幕的左邊的某個位置,UIPanGestureRecognizer纔會起做用。UIScrollView的滑動手勢也是UIPanGestureRecognizer。那在側邊滑動時,讓UIScrollView的不響應事件就OK了嘛,首先想到了繼承UIScrollView 重寫下面的方法,讓滑動側邊時scrollView不響應事件,根據響應者鏈,事件最終會傳遞給下方的滑動手勢。ui

- (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時,也須要滑動切換,滑動返回。spa

因爲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的代理方法。code

- (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的位置在初始位置的時候讓兩個手勢同時啓用就能夠了圖片

相關文章
相關標籤/搜索