更新:虽然我仍然想解决这个问题,但我最终切换到animateWithDuration:delay:options:animations:completion:
并且效果更好。它缺少弹簧提供的末端那种美妙的“反弹”,但至少它是可控的。
我正在尝试为 iOS 创建一个漂亮的手势驱动 UI,但是在获取这些值以产生一个不错的自然感觉应用程序时遇到了一些困难。
我使用animateWithDuration:delay:usingSpringWithDamping:initialSpringVelocity:options:animations:completion:
是因为我喜欢有弹性的弹簧动画。我正在使用velocity
手势识别器在完成状态下给出的速度初始化参数。问题是,如果我足够快地平移并放手,速度是数千,我的视野最终会飞出屏幕,然后以如此令人眼花缭乱的报复来回弹跳。
我什至根据视图需要移动的距离调整动画的持续时间,这样如果只需要几个像素,动画将花费更少的时间。然而,这并没有解决问题。它最终还是会发疯。
我想要发生的是视图应该以用户拖动它的任何速度开始,但它应该在到达目标点时快速减速,并且在结束时只反弹一点(如果速度是合理的,它会这样做) )。
我想知道我是否正确使用了这种方法或值。这是一些代码来显示我在做什么。任何帮助,将不胜感激!
- (void)handlePanGesture:(UIPanGestureRecognizer*)gesture {
CGPoint offset = [gesture translationInView:self.view];
CGPoint velocity = [gesture velocityInView:self.view];
NSLog(@"pan gesture state: %d, offset: %f velocity: %f", gesture.state, offset.x, velocity.x);
static CGFloat initialX = 0;
switch ( gesture.state ) {
case UIGestureRecognizerStateBegan: {
initialX = self.blurView.x;
break; }
case UIGestureRecognizerStateChanged: {
self.blurView.x = initialX + offset.x;
break; }
default:
case UIGestureRecognizerStateCancelled:
case UIGestureRecognizerStateEnded: {
if ( velocity.x > 0 )
[self openMenuWithVelocity:velocity.x];
else
[self closeMenuWithVelocity:velocity.x];
break; }
}
}
- (void)openMenuWithVelocity:(CGFloat)velocity {
if ( velocity < 0 )
velocity = 1.5f;
CGFloat distance = -40 - self.blurView.x;
CGFloat distanceRatio = distance / 260;
NSLog(@"distance: %f ratio: %f", distance, distanceRatio);
[UIView animateWithDuration:(0.9f * distanceRatio) delay:0 usingSpringWithDamping:0.7 initialSpringVelocity:velocity options:UIViewAnimationOptionBeginFromCurrentState animations:^{
self.blurView.x = -40;
} completion:^(BOOL finished) {
self.isMenuOpen = YES;
}];
}