0

私は自分のアプリケーションでモーダルコントロールを表示します。私は、ユーザーがジェスチャーでビューを「軽く叩く」ことができるようにしたいと思います。これはUIGestureRecognizerにフックアップされアニメーションが正常に動作しない

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

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

しかし、何が起こることは完了ブロックがすぐに実行されるということです私はそのために以下のコードを書きました。したがって、ビューが下に移動して(dismissViewControllerAnimatedのため)、同時にoverlay.effectが表示されなくなります。しかし、私が望むのは、私のアニメーションが起こることです。そして、View Controllerがそれを黙って却下することです。

何が問題なのですか?

+0

残りのジェスチャー処理では何が起こっていますか?ジェスチャー状態が変更されたときにビューを移動していますか?パンが終わったときに何かをするだけで奇妙に思えます。 – jrturton

+0

パンが終了したら、それを0に戻しています。それ以外の場合は、ビューを下に移動しています。 – user4992124

+0

しかし、そのコードはあなたの質問にありません – jrturton

答えて

0

これは、UIViewアニメーションブロックがネストされているために発生します。あなたはこのためにdispatch_afterを使用する必要があります。やるべき作業がない場合

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

私は入れ子にしていませんか? 'animateKeyframesWithDuration'にキーフレームを追加するだけです。しかし、View Controllerの解任を遅らせることはできます。 – user4992124

+0

@ user4992124要点は、ブロックをメインブロック内に呼び出すことで、完了ブロックが予想よりも早く実行されるようにすることです。 – the4kman

+0

これにより、まだ瞬時にビューが閉じられます。 – user4992124

0

AのUIViewのキーフレーム(または標準)アニメーションは、直ちにその完了ブロックを実行します。アニメーション化するものがない場合、アニメーションの時間を待つことはありません。

解雇アニメーションを開始する際には、ビューはすでに最終状態にあるため、アニメーションがなく、完了ブロックがすぐに実行されるようです。

関連する問題