0

Ich präsentiere einen View Controller modal in meiner Anwendung. Ich möchte, dass der Benutzer die Ansicht mit einer Geste "wegschnippen" kann. Ich schrieb den Code dafür:Animationen funktionieren nicht richtig

- (void)handlePan:(UIPanGestureRecognizer *)recognizer { 
    CGFloat elasticThreshold = 100; 
    CGFloat dismissThreshold = 200; 
    CGPoint translation = [recognizer translationInView:self.view]; 
    CGFloat newY = 0; 
    CGFloat translationFactor = 0.5; 

    if (recognizer.state == UIGestureRecognizerStateEnded) { 
     if (translation.y < dismissThreshold) { 
      newY = 0; 
     } 
    } else { 
     if (translation.y > elasticThreshold) { 
      CGFloat frictionLength = translation.y - elasticThreshold; 
      CGFloat frictionTranslation = 30 * atan(frictionLength/120) + frictionLength/10; 
      newY = frictionTranslation + (elasticThreshold * translationFactor); 
     } else { 
      newY = translation.y*translationFactor; 
     } 
    } 

    if (translation.y > dismissThreshold) { 
     [UIView animateKeyframesWithDuration:0.5 delay:0.0 options:0 animations:^{ 
      [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.5 animations:^{ 
       self.overlay.effect = nil; 
       self.collectionView.transform = CGAffineTransformMakeTranslation(0, self.view.frame.size.height); 
      }]; 
      [UIView addKeyframeWithRelativeStartTime:0.1 relativeDuration:0.1 animations:^{ 
       self.pageControl.frame = CGRectMake((self.view.frame.size.width-200)/2, self.view.frame.size.height, 200, 20); 
      }]; 
     } completion:^(BOOL finished) { 
      if (finished) { 
       [self dismissViewControllerAnimated:YES completion:nil]; 
      } 
     }]; 
    } else { 
     self.collectionView.transform = CGAffineTransformMakeTranslation(0, newY); 
     self.pageControl.transform = CGAffineTransformMakeTranslation(0, (newY+self.collectionView.frame.size.height)-20); 
    } 
} 

Dies zu einem UIGestureRecognizer angeschlossen ist:

self.pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 
self.pan.delegate = self; 
self.pan.maximumNumberOfTouches = 1; 
[self.view addGestureRecognizer:self.pan]; 

Doch was passiert, ist, dass der Abschluss-Block sofort ausführt. Sie werden sehen, dass sich die Ansicht nach unten bewegt (wegen dismissViewControllerAnimated) und gleichzeitig die overlay.effect verschwindet. Was ich jedoch möchte, ist, dass meine Animationen passieren und sich dann der View-Controller stillschweigend abwendet.

Irgendwelche Ideen, was hier schief läuft?

+0

Was passiert mit dem Rest der Gestenbehandlung? Verschieben Sie die Ansicht, wenn der Gestenstatus geändert wird? Es ist seltsam, nur etwas zu tun, wenn die Pfanne – jrturton

+0

beendet ist. Ich bewege es zurück auf 0, wenn die Pfanne endet. Ansonsten bewege ich den Blick nach unten, ja. – user4992124

+0

aber dieser Code ist nicht in Ihrer Frage – jrturton

Antwort

0

Dies geschieht, weil Sie verschachtelnUIView Animation Blöcke sind. Sie sollten dispatch_after für diesen Einsatz:

double delayInSeconds = 0.5; 
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); 
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
    [self dismissViewControllerAnimated:YES completion:nil]; 
}); 
+0

Ich niste mich nicht? Ich füge einfach Keyframes zu 'animateKeyframesWithDuration' hinzu. Aber die Entlassung des View-Controllers zu verzögern, könnte funktionieren, yeah. – user4992124

+0

@ user4992124 Der Punkt ist, dass Sie Blöcke innerhalb des Hauptblocks aufrufen und den Abschlussblock schneller als erwartet ausführen. – the4kman

+0

Dies führt immer noch dazu, dass die Ansicht fast sofort gelöscht wird. – user4992124

0

A UIView Keyframe (oder Standard) Animation wird seinen Abschluss Block sofort ausgeführt werden, wenn es keine Arbeit zu tun ist. Es wird nicht auf die Dauer der Animation warten, wenn nichts zu animieren ist.

Es scheint, dass in Ihrem Fall, wenn Sie die Kündigung Animation starten, die Ansichten sind bereits in ihrem endgültigen Zustand, daher gibt es keine Animation und der Abschlussblock wird sofort ausgeführt.

Verwandte Themen