0

我在应用程序中以模态方式呈现视图控制器。我希望用户能够用手势“弹开”视图。我写了下面的代码:动画无法正常工作

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

这是迷上了一个UIGestureRecognizer

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消失。然而,我想要的是让我的动画发生,然后视图控制器默默地解散它自己。

任何想法这里有什么问题吗?

+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'。但推迟视图控制器的解雇可能会奏效,是的。 – user4992124

+0

@ user4992124问题是您正在主块内部调用块,并且会触发完成块比预期更早运行。 – the4kman

+0

这仍然导致视图几乎立即被解雇。 – user4992124

0

一个UIView关键帧(或标准)的动画将立即执行其完成块,如果没有工作要做。如果没有任何动画,它将不会等待动画的持续时间。

在你的情况下,当你开始关闭解除动画时,视图已经处于最终状态,因此没有动画,并且完成块立即运行。