0

Je présente un contrôleur de vue de manière modale dans mon application. Je voudrais que l'utilisateur puisse "balayer" la vue d'un geste. J'ai écrit le code ci-dessous pour que:Les animations ne fonctionnent pas correctement

- (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); 
    } 
} 

Ceci est relié à un UIGestureRecognizer:

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

Cependant, ce qui se passe est que le bloc d'achèvement exécute immédiatement. Donc, vous verrez la vue descendre (à cause de dismissViewControllerAnimated) et en même temps voir le overlay.effect s'en aller. Cependant, ce que je voudrais, c'est que mes animations se produisent, puis que le contrôleur de vue se retire en silence.

Des idées sur ce qui ne va pas ici?

+0

Que se passe-t-il avec le reste de la manipulation des gestes? Déplacez-vous la vue lorsque l'état du geste est modifié? Il semble étrange de ne rien faire quand le panoramique est terminé – jrturton

+0

Je le ramène à 0 quand le panoramique se termine. Sinon, je déplace la vue, oui. – user4992124

+0

mais ce code n'est pas dans votre question – jrturton

Répondre

0

Cela se produit car vous êtes imbriquantUIView blocs d'animation. Vous devez utiliser dispatch_after pour cela:

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

Je n'emboite pas? Je viens d'ajouter des images clés à 'animateKeyframesWithDuration'. Mais retarder le renvoi du contrôleur de vue pourrait fonctionner, oui. – user4992124

+0

@ user4992124 Le fait est que vous invoquez des blocs à l'intérieur du bloc principal et que le bloc d'achèvement se déclenche plus tôt que prévu. – the4kman

+0

Cela entraîne toujours le rejet de la vue presque instantanément. – user4992124

0

A UIView image-clé (ou standard) animation exécute son bloc d'achèvement immédiatement s'il n'y a pas de travail à faire. Il n'attendra pas la durée de l'animation s'il n'y a rien à animer.

Il semble que dans votre cas lorsque vous démarrez l'animation de suppression, les vues sont déjà dans leur état final, il n'y a donc pas d'animation et le bloc d'achèvement est exécuté immédiatement.