2012-05-23 12 views
12

Sto spostando l'oggetto UIView usando UIPanGestureRecognizer - quanto trascino il dito sullo schermo, tanto sposto la vista nella stessa direzione (solo in X - a sinistra oa destra, Y non sta cambiando). Funziona bene, ma con (molto evidente) ritardo.perché c'è un ritardo nello spostamento dell'oggetto usando UIPanGestureRecognizer

Qui è il metodo che gestisce l'evento UIPanGestureRecognizer:

-(void)movePages:(UIPanGestureRecognizer *)sender 
{ 
    if(switchingMode == 1){ 
     if([sender state] == UIGestureRecognizerStateBegan){ 
      fingerStartPosition = [sender locationInView:self.view].x; 
      viewStartPosition = [[viewControllers objectAtIndex:activeViewControllerIndex] view].center; 
     } 
     [[[[viewControllers objectAtIndex:activeViewControllerIndex] view] layer] setPosition:CGPointMake(viewStartPosition.x - (fingerStartPosition - [sender locationInView:self.view].x) , viewStartPosition.y)]; 

    } 
} 

Ho cercato di impostare la posizione della vista utilizzando il suo strato, ho anche provato modificando il telaio, utilizzando animazioni di diversa durata, ma tutto si è comportato allo stesso modo. Qualche idea del perché questo ritardo si verifica?

+0

Hai trovato una soluzione? Avendolo anche – Ixx

risposta

35

Utilizzare un UILongPressGestureRecognizer e impostare minimumPressDuration su 0.0. Questo riconosce all'istante e ricevi tutti gli stessi aggiornamenti incluso lo UIGestureRecognizerStateChanged con la posizione aggiornata.

+0

Questa è una soluzione eccezionale! –

+1

Pensavo aggiungessi: stavo avendo un problema con un campo di disegno su un modulo quando il modulo è stato ingrandito (ridimensionato) in - se inizi a disegnare subito si scorrerebbe invece, dovresti tenere il dito in posizione per un frazione seconda prima del disegno. Facendo questo con una scala del 100% non è successo, avrebbe iniziato a disegnare all'istante. Sostituire UIPanGestureRecognizer con UILongPressGestureRecognizer ha funzionato a meraviglia! – EvilGeniusJamie

+3

Dovrai anche impostare il 'allowableMovement' di' UILongPressGestureRecognizer' su 'CGFloat.infinity'. Altrimenti, il gesto si annullerà dopo aver trascinato una breve distanza (10 pt). –

1

GestureRecognizer non può essere sicuro, se si tratta di un gesto di panoramica, prima di spostare il dito di alcuni pixel. Non conosco il valore esatto della tolleranza, ma è per questo che ritardi.

Documentazione:

una panoramica gesto è continuo. Inizia quando il numero minimo di dita consentite si è spostato abbastanza da essere considerato un riquadro.

Se si desidera il movimento istantaneo, è probabilmente necessario creare la propria logica utilizzando touchesMoved:.

Un altro approccio potrebbe essere quello di animare il primo punto riconosciuto. Ma ciò non rimuove il ritardo. Per questo approccio potresti dare un'occhiata al mio JDDroppableView su github.

+0

non è il ritardo all'inizio del trascinamento, voglio dire ... quando questo ritardo è finito e l'oggetto è già in movimento, si muove con ritardo. Trascino, l'oggetto inizia a muoversi, ma è un po 'lento e devo aspettare che l'oggetto raggiunga la posizione richiesta – Michael

1

Ho scoperto che era più rapido rispondere se si utilizzano solo i tocchi regolari Began, Moved and Ended. Ho persino creato una sottoclasse di UIGestureRecognizer, e ha comunque avuto un ritardo nel gesto di panning. Anche se i tocchi introdotti da UIGestureRecognizer si attivassero in tempo, il cambio di stato impiegherebbe mezzo secondo per cambiare il suo stato ... Sembra più veloce usare semplicemente un vecchio TouchesBegan, specialmente se la CPU sta facendo molto.

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) 
{ 
    if touches.count == 1 
    { 
     initialTouchLocation = (touches.first?.locationInView(self).x)! 
    } 
} 
override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) 
{ 
    if touches.count == 1 
    { 
     let locationInView = touches.first?.locationInView(self) 
     if !thresholdHit 
     { 
      //this is the threshold for x movement in order to trigger the panning... 
      if abs(initialTouchLocation - locationInView!.x) > 1 
      { 
       thresholdHit = true 
      } 
     } 
     else 
     { 
      if (self.frame.width != CGFloat(screenSize)) 
      { 
       let panDelta = initialTouchLocation - locationInView!.x 
      } 
     } 
    } 
} 
+0

concordato. Nel mio caso, voglio evidenziare l'oggetto che sto trascinando in giro. Per questo sembra buono, il punto saliente deve essere disegnato immediatamente. Sembra che la roba di UIGestureRecognizer sia un po 'lenta nell'inviare quell'azione iniziale all'obiettivo che non è assolutamente utile per il mio caso d'uso. –

Problemi correlati