2012-01-03 2 views
11

Ho un UIScrollView con il paging abilitato e ho aggiunto il mio UIPanGestureRegonizer. In determinati casi, il controller di visualizzazione imposterà scrollview.scrollEnabled = NO e quindi aggiungerà il riconoscimento pan gesture ad esso (non sto utilizzando il riconoscitore dello scrollview).Scorrimento continuo tra UIPanGestureRecognizer e riattivato UIScrollView

Quindi, lo scorrimento è disattivato, ma sono in attesa di un tocco utente dal mio riconoscimento gestuale. Quando riconosce, chiama la sua azione in cui riabilita lo scorrimento.

Il problema è che, mentre l'utente ha ancora un dito verso il basso, il mio ScrollView non tiene traccia con il dito. Non inizia a scorrere finché il dito non viene sollevato e quindi trascinato di nuovo. Quindi il mio gesto di riconoscimento sta inghiottendo tutti i tocchi e non inoltrando alcuno alla scrollview.

Ho provato a cambiare panGestureRecognizer.cancelsTouchesInView = NO; ma non sembra avere alcun effetto (attualmente sto rimuovendo questo riconoscimento non appena riabilito lo scorrimento ma se lo faccio o no non risolve il mio problema) . Ho anche esaminato le proprietà delays... di UIGestureRecognizer ma non sembrano essere d'aiuto.

Qualche idea? Come posso ottenere che questi eventi continuino ad essere inoltrati alla mia scrollview?

+0

Forse si tenta di tornare 'affermativa in' gestureRecognizer: shouldRecognizeSimultaneouslyWithGestureRecognizer: metodo '? – Hejazi

+0

@Hejazi Sì, ho implementato anche questo metodo delegato (e impostato il mio delegato) ma non viene chiamato mentre il dito è ancora inattivo (solo una volta che ho sollevato e messo di nuovo il dito verso il basso viene chiamato questo metodo delegato) . – jbrennan

risposta

5

La risposta è un po 'più semplice se si utilizza solo iOS 5 e versioni successive, perché in questo caso è necessario riutilizzare la proprietà panGestureRecognizer di UIScrollView.

In ogni caso, il passaggio chiave è NON riutilizzare scrollEnabled, ma invece di sottoclasse UIScrollView, creare la propria proprietà per gestire questo stato e sovrascrivere setContentOffset :.

- (void) setContentOffset:(CGPoint)contentOffset 
    { 
     if(self.programaticScrollEnabled) 
      [super setContentOffset:contentOffset]; 
    } 

Ecco un possibile iOS 4+ Soluzione:

  1. sottoclasse UIScrollView (o sottoclasse un'altra sottoclasse di UIScrollView, a seconda delle esigenze).
  2. Sostituire tutti gli inizializzatori per garantire che venga chiamato il codice di configurazione.
  3. Dichiarare la proprietà BOOL e sovrascrivere setContentOffset: come descritto sopra.
  4. Nel codice di impostazione, impostare un UIPanGestureRecognizer e impostare la variabile di stato per consentire lo scorrimento programmatico (assumendo che è lo stato di default che si desidera):

    panRecognizer = [[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)] autorelease]; 
    //These properties may change according to your needs 
    panRecognizer.cancelsTouchesInView = NO; 
    panRecognizer.delaysTouchesBegan = NO; 
    panRecognizer.delaysTouchesEnded = NO; 
    [self addGestureRecognizer:panRecognizer]; 
    panRecognizer.delegate = self; 
    
    self.programaticScrollEnabled = YES; 
    
  5. gestire quali gesti possono verificarsi contemporaneamente. Nel mio caso:

    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer 
    { 
        return YES; 
    } 
    
  6. Ruotare scorrimento programmatico spalle ovunque ne abbiate bisogno. Per esempio:

    - (void)handleGesture:(UIPanGestureRecognizer *)gestureRecognizer 
    { 
        self.programaticScrollEnabled = YES; 
    } 
    
    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer 
    { 
        self.programaticScrollEnabled = YES; 
        return YES; 
    }