2012-05-23 8 views
12

Muevo el objeto UIView usando UIPanGestureRecognizer - cuánto arrastro mi dedo en la pantalla, tanto que muevo la vista en la misma dirección (solo en X - izquierda o derecha, Y no está cambiando). Funciona bien, pero con retraso (muy notable).por qué hay un retraso cuando muevo el objeto usando UIPanGestureRecognizer

Aquí es el método que controla el 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)]; 

    } 
} 

He tratado de establecer la posición de la vista con su capa, también he intentado fijar el marco, usando animaciones con diferentes duraciones, pero todo se comportó igual. ¿Alguna idea de por qué ocurre este retraso?

+0

¿Encontró una solución? También teniendo – Ixx

Respuesta

35

Usa un UILongPressGestureRecognizer y configura el minimumPressDuration en 0.0. Esto reconoce instantáneamente y obtienes todas las mismas actualizaciones, incluido el UIGestureRecognizerStateChanged con la ubicación actualizada.

+0

¡Esta es una gran solución! –

+1

Pensé que agregaría: tenía un problema con un campo de dibujo en un formulario cuando se ampliaba (escalaba) el formulario. Si comenzaba a dibujar inmediatamente, se desplazaría en su lugar, tendría que mantener el dedo en su lugar para un dividir segundo antes de dibujar. Hacer esto al 100% de la escala no sucedió, comenzaría a dibujar al instante. ¡Reemplazar el UIPanGestureRecognizer con UILongPressGestureRecognizer funcionó! – EvilGeniusJamie

+3

También deseará establecer el 'allowableMovement' de' UILongPressGestureRecognizer' en 'CGFloat.infinity'. De lo contrario, el gesto se cancelará después de arrastrar una distancia corta (10 puntos). –

1

El GestureRecognizer no puede estar seguro, si se trata de un movimiento panorámico, antes de mover el dedo algunos píxeles. No sé el valor de tolerancia exacto, pero es por eso que sientes un retraso.

Documentación:

A panning gesto es continua. Comienza cuando la cantidad mínima de dedos permitidos se ha movido lo suficiente como para ser considerada una sartén.

Si desea un movimiento instantáneo, probablemente necesite construir su propia lógica usando touchesMoved:.

Otro enfoque podría ser animar al primer punto reconocido. Pero eso no elimina la demora. Para ese enfoque, puedes echar un vistazo a mi JDDroppableView en github.

+0

no es el retraso al comienzo del arrastre quiero decir ... cuando este retraso ha terminado, y el objeto ya se está moviendo, se está moviendo con retraso. Arrastro, el objeto comienza a moverse, pero es un poco lento y tengo que esperar hasta que el objeto llegue a la posición requerida – Michael

1

Descubrí que respondía con mayor rapidez si solo usaba toques regulares, comienza, finalizaba y finalizaba. Incluso subclasé un UIGestureRecognizer, y todavía tenía un retraso en el gesto de panoramización. A pesar de que los toques dentro del UIGestureRecognizer se dispararían a tiempo, el cambio de estado tardaría medio segundo en cambiar su estado ... Parece más rápido usar simplemente un viejo TouchesBegan, especialmente si tu CPU está haciendo mucho.

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

De acuerdo. En mi caso, quiero resaltar el elemento que estoy arrastrando. Para que se vea bien, lo más destacado debe dibujarse de inmediato. Parece que el material de UIGestureRecognizer es un poco lento al enviar esa acción inicial al objetivo, que no sirve para nada en mi caso de uso. –

Cuestiones relacionadas