6

Sto provando ad aggiungere un indicatore di riconoscimento pan a una vista contenente una scrollview, ma suppongo di avere problemi con le priorità.Conflitto UIPanGestureRecognizer con scrollview

mio UIView globale ha un UIPanGestureRecognizer impostato in questo modo:

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

Voglio riconoscere questo gesto per visualizzare un'altra vista dal basso con una sorta di pinch down-to-up.

Il problema è che la scrollview sta riconoscendo il proprio gesto pan prima del mio.

Così ho cercato di ritardare grazie a:

[_scrollView.panGestureRecognizer requireGestureRecognizerToFail:_bottomPanGestureRecognizer]; 

E sta funzionando, l'evento ScrollView viene licenziato dopo i miei due dito verso il basso fino riconoscitore, ma il problema è ora quando uso un solo dito per scorrere la scrollview, la scroll funziona dopo un piccolo ritardo.

Mi piacerebbe non avere ritardi per questo evento, è possibile? Ogni idea è benvenuta!

Cheers.

Cyril

+0

Hai provato a impostare 'maximumNumberOfTouches' di' _scrollView.panGestureRecognizer' a '1'? – kovpas

+0

Sì, ma stranamente, sembra che questa condizione sia ignorata. – cyrilPA

+1

Bene, un'altra opzione è implementare 'UIGestureRecognizerDelegate''s' gestureRecognizerShouldBegin: 'e controllare il numero di tocchi lì. Quindi, se si tratta di due tocchi, 'return NO' – kovpas

risposta

7

Nel caso in cui non è ancora risolto, ho risolto il problema per me.

Ho aggiunto un UIPanGestureRecognizer a un UIScrollView per rilevare due movimenti di spostamento delle dita e il comportamento predefinito di UIScrollView (scorrendo verso qualcosa) funziona ancora.

Quindi quello che ho fatto è quello di aggiungere l'UIPanGestureReconizer alla UIScrollView:

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

Dopo questo ho aggiunto il codice:

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

    return YES; 
} 

Dopo questo, ho implementato il metodo di azione di riconoscimento gesto padella.

- (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:

Nel caso in cui si potrebbe desiderare di integrare il colpo indietro funzionalità dal vostro navigationController, si dovrebbe integrare seguente codice:

- (void) viewDidLoad { 

    [super viewDidLoad]; 


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

     self.navigationController.interactivePopGestureRecognizer.enabled = YES; 

     self.navigationController.interactivePopGestureRecognizer.delegate = nil; 
    } 

    //setup view controller 
} 

e

- (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

Grazie @NicTesla – channi

+0

Prego :) – NicTesla

1

Implementare il delegato di panRecognizer su e nable contemporaneamente riconoscere 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; 
}