2

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

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

谢谢你。


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

2 回答 2

6

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

#import <QuartzCore/QuartzCore.h>

- (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 <QuartzCore/QuartzCore.h>

- (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像这段代码一样保存,这样如果你抓住被拖离中心一点的视图,它就不会在你身上跳动。

于 2013-01-10T19:37:06.953 回答
1

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

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

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

于 2013-01-10T19:50:44.240 回答