UIPanGestureRecognizer – 立即移动视图

我只需要根据平移手势移动一些视图。 问题是它不会立即发生,就像苹果地图一样,如果我将手指放在一个点上,并将其快速移动到任何方向,视图将会延迟移动,这意味着我将能够看到指出我把手指放在上面,这就是我不想要的。

也许这是不可能的,因为硬件限制,因为在模拟器中它工作正常。 或者也许有一种我不知道的更好的方式。

谢谢。


- (IBAction)pan:(UIPanGestureRecognizer *)sender { CGPoint center = [sender locationInView:sender.view]; self.myView.center = center; } 

当我第一次回答时,我假设被拖动的视图有些复杂(例如,一个大的CALayer阴影,这可能是计算上昂贵的)。 因此我的原始答案如下。 但是在随后的评论交流中,已经发现其中一个按钮具有脉冲动画,这更可能是问题。 如果拖动性能不可接受,则在拖动视图期间应暂停动画 。 从而:

 #import  - (IBAction)pan:(UIPanGestureRecognizer *)gesture { static CGPoint originalCenter; if (gesture.state == UIGestureRecognizerStateBegan) { originalCenter = gesture.view.center; [self pauseLayer:gesture.view.layer]; } else if (gesture.state == UIGestureRecognizerStateChanged) { CGPoint translate = [gesture translationInView:gesture.view.superview]; gesture.view.center = CGPointMake(originalCenter.x + translate.x, originalCenter.y + translate.y); } else if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateFailed || gesture.state == UIGestureRecognizerStateCancelled) { [self resumeLayer:gesture.view.layer]; } } -(void)pauseLayer:(CALayer*)layer { CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil]; layer.speed = 0.0; layer.timeOffset = pausedTime; } -(void)resumeLayer:(CALayer*)layer { CFTimeInterval pausedTime = [layer timeOffset]; layer.speed = 1.0; layer.timeOffset = 0.0; layer.beginTime = 0.0; CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime; layer.beginTime = timeSincePause; } 

显然,这可以与图像的光栅化相结合,如下所述,但我会先尝试暂停动画,如上所述。


原始答案:

如果您拖动的视图非常复杂,您可以尝试栅格化它。

  1. QuartzCore.framework添加到目标的“使用库链接二进制”设置。

  2. 然后相应地调整源光栅化。

如:

 #import  - (IBAction)pan:(UIPanGestureRecognizer *)gesture { static CGPoint originalCenter; if (gesture.state == UIGestureRecognizerStateBegan) { originalCenter = gesture.view.center; gesture.view.layer.shouldRasterize = YES; } if (gesture.state == UIGestureRecognizerStateChanged) { CGPoint translate = [gesture translationInView:gesture.view.superview]; gesture.view.center = CGPointMake(originalCenter.x + translate.x, originalCenter.y + translate.y); } if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateFailed || gesture.state == UIGestureRecognizerStateCancelled) { gesture.view.layer.shouldRasterize = NO; } } 

顺便说一句,我建议像这样的代码一样保存originalCenter ,这样如果你抓住视图被拖离中心一点点,它就不会在你身上猛烈地跳跃。

设置中心点的新值时,请尝试禁用动画。

 - (IBAction)pan:(UIPanGestureRecognizer *)sender { CGPoint center = [sender locationInView:sender.view]; [CATransaction begin]; [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; self.myView.center = center; [CATransaction commit]; } 

如果这有助于你可以尝试用更快的动画来平滑它。

您还可以尝试禁用此处所述的动画: 在iOS4 +中显式禁用UIView动画

不久:

 - (IBAction)pan:(UIPanGestureRecognizer *)sender { CGPoint center = [sender locationInView:sender.view]; [UIView setAnimationsEnabled:NO]; self.myView.center = center; [UIView setAnimationsEnabled:YES]; } 

一旦你设法在重新定位期间禁用所有动画,它就取决于硬件和代码的速度。