我在我的应用程序中以模态方式呈现视图控制器。我希望用户能够轻弹"用手势远离视线。我为此写了下面的代码:
- (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 :(得分: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];
});
答案 1 :(得分:0)
如果没有工作要做,UIView关键帧(或标准)动画将立即执行其完成块。如果没有任何动画效果,它将不会等待动画的持续时间。
似乎在您开始关闭动画的情况下,视图已经处于最终状态,因此没有动画并且立即运行完成块。