Search code examples
ioscore-plotuipinchgesturerecognizer

Trouble pinch zooming core plot graph in iOS


I have created a graph with Core Plot and am trying to use the pinch zoom feature. I want the pinch to work in just the x axis or just the y axis. I have accomplished this by using the following code in a pinch gesture recognizer that I put in.

- (void)handlePinch:(UIPinchGestureRecognizer*)recognizer
{
//NSLog(@"We are pinching");
//This allows you to figure out which direction the pinch is occuring HORIZ or VERT

if (recognizer.state != UIGestureRecognizerStateCancelled)  //If gesture is occuring
{
    _startScale = 1.0f;

    if (recognizer.numberOfTouches == 2)  //With two fingers
    {
        CGPoint firstPoint = [recognizer locationOfTouch:0 inView:recognizer.view];
        CGPoint secondPoint = [recognizer locationOfTouch:1 inView:recognizer.view];

        CGFloat tangent = fabs(secondPoint.y - firstPoint.y) / (secondPoint.x - firstPoint.x);

        CGFloat angle = fabs(tangent);
        //NSLog(@"angle is %f", angle);

        if (angle <= 0.2679491924f)
        {
            //NSLog(@"HORIZONTAL");
            _zoomX = _startScale * recognizer.scale;

        }
        else if (angle >= 3.7320508076f)
        {
            //NSLog(@"VERTICAL");
            _zoomY = startScale * recognizer.scale;
        }
        else
        {
            //NSLog(@"BOTH");
        }
    }
}

[self changePlotRange];

}

The method changePlotRange is as follows.

- (void)changePlotRange
{

CPTGraph *graph = _hostView.hostedGraph;
CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *) graph.defaultPlotSpace;

plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromCGFloat(_Xmin * _zoomX) length:CPTDecimalFromCGFloat((_Xmax - _Xmin) * _zoomX)];

plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromCGFloat(_Ymin * _zoomY) length:CPTDecimalFromCGFloat((_Ymax - _Ymin) * _zoomY)];
}

This works great and I can zoom in and out on either axis independently. However, when I start again to pinch, the scale jumps back to one and the graph bounces back to the original scale so you need to scale again. I want this to work like a picture, pinch a little, zoom a little, pinch some more and the picture zooms from the last scale.

So within the pinch gesture, I tried to keep the current scale and return it later with...

if (recognizer.state == UIGestureRecognizerStateEnded)
{
    _startScale = _zoomX;
}

I put this inside the handlePinch method. But it still goes back to a scale of one. Any help would be appreciated as I have searched and tried numerous things over the past three days.


Solution

  • You need to save the ending zoom values for both x and y separately since they will probably be different. Also, don't reset the start scale at the beginning of the gesture recognizer handler—you want it to use the previous zoom value.