2012-05-23 6 views
12

Ich verschiebe UIView Objekt mit UIPanGestureRecognizer - wie viel ziehe ich meinen Finger auf dem Bildschirm, so viel ich die Ansicht in die gleiche Richtung bewegen (nur in X - links oder rechts, Y ändert sich nicht). Es funktioniert gut, aber mit (sehr auffällig) Verzögerung.Warum gibt es eine Verzögerung, wenn Objekt mit UIPanGestureRecognizer bewegt wird

Hier ist die Methode, die das Ereignis behandelt 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)]; 

    } 
} 

Ich habe versucht Position der Ansicht einzustellen seine Schicht verwendet wird, habe ich versucht, auch den Rahmen einstellen, Animationen mit unterschiedlichen Laufzeiten verwenden, aber alles verhielt sich genauso. Irgendeine Idee, warum diese Verzögerung auftritt?

+0

Haben Sie eine Lösung gefunden? Auch wenn es – Ixx

Antwort

35

Verwenden Sie eine UILongPressGestureRecognizer und setzen Sie die minimumPressDuration auf 0.0. Dies erkennt sofort und Sie erhalten alle die gleichen Updates einschließlich der UIGestureRecognizerStateChanged mit dem aktualisierten Speicherort.

+0

Dies ist ein guter Workaround! –

+1

Ich dachte, ich würde hinzufügen - ich hatte ein Problem mit einem Zeichnungsfeld auf einem Formular, wenn das Formular gezoomt (skaliert) wurde - wenn Sie sofort beginnen zu zeichnen, würde es stattdessen scrollen, müssten Sie Ihren Finger für einen halten Sekundenbruchteile vor dem Zeichnen. Bei 100% Skalierung ist das nicht passiert, es würde sofort gezeichnet werden. Das Ersetzen des UIPanGestureRecognizer durch UILongPressGestureRecognizer funktionierte ein Vergnügen! – EvilGeniusJamie

+3

Sie sollten auch die 'UGLongPressGestureRecognizer'' zulässige Bewegung auf' CGFloat.infinity' setzen. Andernfalls wird die Geste nach kurzem Ziehen (10pt) abgebrochen. –

1

Der GestureRecognizer kann nicht sicher sein, ob es sich um eine Schwenkgeste handelt, bevor Sie mit dem Finger einige Pixel bewegt haben. Ich kenne den genauen Toleranzwert nicht, aber deshalb verspüren Sie eine Verzögerung.

Dokumentation:

Eine Panning Geste ist kontinuierlich. Es beginnt, wenn die minimale Anzahl der erlaubten Finger sich genug bewegt hat, um als Schwenken betrachtet zu werden.

Wenn Sie sofortige Bewegung wünschen, müssen Sie wahrscheinlich Ihre eigene Logik mit touchesMoved: erstellen.

könnte Ein weiterer Ansatz, zu dem ersten erkannten Punkt zu animieren. Aber das beseitigt die Verzögerung nicht. Für diesen Ansatz können Sie sich meine JDDroppableView auf GitHub ansehen.

+0

ist, ist es nicht die Verzögerung zu Beginn des Ziehens meine ich ... wenn diese Verzögerung vorbei ist und das Objekt sich bereits bewegt, bewegt es sich mit Verzögerung. Ich ziehe, das Objekt beginnt sich zu bewegen, aber es ist langsam und ich muss warten, bis das Objekt an die gewünschte Position kommt. – Michael

1

Ich fand, dass es schneller reagierte, wenn Sie nur regelmäßige BerührungenBegan, Moved und Ended verwenden. Ich unterordnete sogar einen UIGestureRecognizer, und es hatte immer noch eine Verzögerung bei der Schwenkgeste. Auch wenn die Berührungen innerhalb des UIGestureRecognizers pünktlich ausgelöst würden, würde der Zustandswechsel eine halbe Sekunde dauern, um seinen Zustand zu ändern ... Es scheint schneller zu sein, einfach einen einfachen alten TouchesBegan zu verwenden, besonders wenn es sich bei CPU um eine Menge handelt.

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

Einverstanden. In meinem Fall möchte ich den Gegenstand hervorheben, den ich herumschleppe. Damit dies gut aussieht, muss das Highlight sofort gezeichnet werden. Scheint so, als ob das UIGestureRecognizer-Zeug beim Senden dieser ersten Aktion an das Ziel etwas langsam ist, was für meinen Anwendungsfall überhaupt nicht nützlich ist. –