When I first answered, I was presuming that there was something complicated about the view being dragged (e.g. a large CALayer
shadow, which can be computationally expensive). Hence my original answer below. But in a subsequent exchange of comments, it has been discovered that one of the buttons had an pulsing animation, which is more likely to be the problem. The animation should be suspended during the dragging of the view if the dragging performance is not acceptable. Thus:
#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;
}
Clearly, this can be combined with the rasterization of the image, discussed below, but I would try suspending the animation, like above, first.
Original answer:
If your view being dragged is at all complicated, you could try rasterizing it.
Add QuartzCore.framework
to your target's "Link binary with libraries" settings.
And then adjust the source to rasterize accordingly.
Such as:
#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;
}
}
As an aside, I'd suggest saving the originalCenter
like this code does, so that if you grab the view being dragged a little off center, it won't jump jarringly on you.