6

Próbuję dodać rozpoznawcę gestu panoramy do widoku zawierającego scrollview, ale domyślam się, że mam problemy z priorytetami.Konflikt UIPanGestureRecognizer z przewijaniem

Moja globalny UIView ma UIPanGestureRecognizer ustawione tak:

_bottomPanGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(bottomPanGestureDetected:)]; 
_bottomPanGestureRecognizer.minimumNumberOfTouches = 2; 
_bottomPanGestureRecognizer.maximumNumberOfTouches = 2; 
_bottomPanGestureRecognizer.delaysTouchesBegan = NO; 
_bottomPanGestureRecognizer.delaysTouchesEnded = NO; 

chcę rozpoznać ten gest, aby wyświetlić inny widok od dołu z jakimś szczyptą dół-up.

Problem polega na tym, że scrollview rozpoznaje własny gest panoramy przed moim.

Więc starałem się opóźnić to dzięki:

[_scrollView.panGestureRecognizer requireGestureRecognizerToFail:_bottomPanGestureRecognizer]; 

I to działa, zdarzenie Scrollview jest zwolniony po moich dwóch palec w dół, aby się rozpoznawania, ale problem jest teraz, kiedy używać tylko jednego palca do przewijaj w przewijanym widoku, a scroll działa po niewielkim opóźnieniu.

Chciałbym nie mieć żadnych opóźnień na to wydarzenie, czy to możliwe? Każdy pomysł mile widziany!

Pozdrawiam.

Cyril

+0

Czy próbowałeś ustawić 'maximumNumberOfTouches' od' '1 'do _scrollView.panGestureRecognizer'? – kovpas

+0

Tak, ale dziwnie, wygląda na to, że ten warunek jest ignorowany. – cyrilPA

+1

Inną opcją jest zaimplementowanie 'gestureRecognizerShouldBegin:' UIGestureRecognizerDelegate' i sprawdzenie liczby dotknięć tam. Więc jeśli to dwa dotknięcia, 'return NO' – kovpas

Odpowiedz

7

W przypadku, gdy nie został jeszcze rozwiązany, I rozwiązać problem dla mnie.

Dodałem UIPanGestureRecognizer do UIScrollView, aby wykryć gesty przesuwania dwoma palcami i domyślne zachowanie UIScrollView (przewijanie do czegoś) wciąż działa.

Więc co zrobiłem jest dodanie UIPanGestureReconizer do UIScrollView:

UIPanGestureRecognizer *pangestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(displayReloadIndicator:)]; 
pangestureRecognizer.minimumNumberOfTouches = 2; 
pangestureRecognizer.delegate = self; 
[self.scrollView addGestureRecognizer:pangestureRecognizer]; 
[pangestureRecognizer release]; 

Potem dodałem kod:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { 

    return YES; 
} 

Po tym, I wdrożone patelni aparatów rozpoznawania gest metody działania.

- (void) displayReloadIndicator:(UIPanGestureRecognizer*) panGestureRecognizer { 

    UIGestureRecognizerState gestureRecognizerState = gestureRecognizer.state; 

    CGPoint translation = [gestureRecognizer translationInView:self.scv_bibgesamt]; 

    if (gestureRecognizerState == UIGestureRecognizerStateBegan) { 

     // create a UIView with all the Pull Refresh Headers and add to UIScrollView 
     // This is really much lines of code, but its simply creating a UIView (later you'll find a myRefreshHeaderView, which is my base view) and add UIElements e.g. UIActivityIndicatorView, a UILabel and a UIImageView on it 
     // In iOS 6 you will also have the possibility to add a UIRefreshControl to your UIScrollView 

    } 

    else if (gestureRecognizerState == UIGestureRecognizerStateEnded 
      || gestureRecognizerState == UIGestureRecognizerStateCancelled) { 

     if (translation.y >= _myRefreshHeaderView.frame.size.height + 12) { // _myRefreshHeaderView is my baseview 

     //so the UIScrollView has been dragged down with two fingers over a specific point and have been release now, so we can refresh the content on the UIScrollView 
     [self refreshContent]; 

     //animatly display the refresh view as the top content of the UIScrollView 
     [self.scrollView setContentOffset:CGPointMake(0, myRefreshHeaderView.frame.size.height) animated:YES]; 
    } 

    else { 

     //the UIScrollView has not been dragged over a specific point so don't do anything (just scroll back to origin) 
     [self.scrollView setContentOffset:CGPointMake(0, 0) animated:YES]; 

     //remove the view (because it's no longer needed) 
     [_myRefreshHeaderView removeFromSuperview]; 
    } 
} 

UPDATE:

W przypadku możesz zintegrować bezstykowa wstecz funkcjonalność z navigationcontroller należy zintegrować następujący kod:

- (void) viewDidLoad { 

    [super viewDidLoad]; 


    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) { 

     self.navigationController.interactivePopGestureRecognizer.enabled = YES; 

     self.navigationController.interactivePopGestureRecognizer.delegate = nil; 
    } 

    //setup view controller 
} 

i

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { 

    if (gestureRecognizer == _panGestureRecognizer 
     && [self.navigationController.viewControllers count] > 1) { 

     CGPoint point = [touch locationInView:self.view.window]; 

     if (point.x < 20 
      || point.x > self.view.window.frame.size.width - 20) { 

      return NO; 
     } 
    } 

    return YES; 
} 
+0

Dzięki @NicTesla – channi

+0

Nie ma za co :) – NicTesla

1

Wykonaj delegowanie PanRecognizer na adres e nable jednocześnie rozpoznać UIScrollView UIGestureRecognizer

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 
{ 
    if (_panRecognizer == gestureRecognizer) { 
     if ([otherGestureRecognizer.view isKindOfClass:UIScrollView.class]) { 
      UIScrollView *scrollView = (UIScrollView *)otherGestureRecognizer.view; 
      if (scrollView.contentOffset.x == 0) { 
       return YES; 
      } 
     } 
    } 

    return NO; 
}