Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using PinchGesture; how can I zoom in to where a user's fingers actually "pinch"?

I've implemented the UIPinchGestureRecognizer on a UIImageView in my app, however no matter where I pinch on the image, it seems to zoom into the same spot. Does anyone know how I can make it zoom in to where a user actually "pinches"? See code below.

ViewController.m

 - (IBAction)scaleImage:(UIPinchGestureRecognizer *)recognizer {

   recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
   recognizer.scale = 1; 

 }

 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
{
    BOOL shouldReceiveTouch = YES;

    if (gestureRecognizer == tap) {
        shouldReceiveTouch = (touch.view == featureImage);
    }
    return shouldReceiveTouch;
}
like image 544
Brittany Avatar asked Sep 16 '14 00:09

Brittany


People also ask

How do you zoom in with a pinch?

Pinch-to-zoom refers to the multi-touch gesture that zooms in or out of the displayed content on a device with a touch screen. These devices include a smartphones and tablets. To use pinch-to-zoom, touch two fingers on the touch screen, and move them apart to zoom in, or together to zoom out.

How do you do a pinch out gesture?

To zoom in on an item on the screen, place your thumb and index finger tips together and place lightly on the screen, when slowly move your thumb and finger apart. Zooming in is sometimes called pinching out, because you're spreading your fingers, like a reverse pinch.

What is a pinch gesture?

Pinch describes a finger gesture used with a touch screen interface that supports multi-touch. The user touches the screen with two or more fingers, and moves them together or apart to zoom in or out. This function is also referred to as a semantic zoom or pinch-to-zoom.

What does it mean pinch to zoom?

What is pinch-to-zoom? Pinch-to-zoom is when a user uses two fingers and pinches to zoom in or out on their mobile device. While it wasn't present on the original touchscreen phones, pinch-to-zoom is now a nearly universal motion for adjusting size on touchscreen devices.


1 Answers

A scale transform leaves the origin (0, 0) untouched. So to scale a view around a particular point, you must first translate that point to the origin, then apply the scale, then translate back.

- (IBAction)pinchGestureDidFire:(UIPinchGestureRecognizer *)pinch {

First, we get the view being pinched.

    UIView *pinchView = pinch.view;

To compute the center of the pinch, we'll need the midpoint of the view's bounds, so we get the bounds too:

    CGRect bounds = pinchView.bounds;

The center is based on the centroid of the pinch's touches, which we get this way:

    CGPoint pinchCenter = [pinch locationInView:pinchView];

But we actually need the pinch offset relative to the center of the view, because the view's transform is relative to the center of the view by default. (You can change this by changing the view's layer.anchorPoint.)

    pinchCenter.x -= CGRectGetMidX(bounds);
    pinchCenter.y -= CGRectGetMidY(bounds);

Now we can update the view's transform. First we get its current transform:

    CGAffineTransform transform = pinchView.transform;

Then we update it to translate the pinch center to the origin:

    transform = CGAffineTransformTranslate(transform, pinchCenter.x, pinchCenter.y);

Now we can apply the scale:

    CGFloat scale = pinch.scale;
    transform = CGAffineTransformScale(transform, scale, scale);

Then we translate the view back:

    transform = CGAffineTransformTranslate(transform, -pinchCenter.x, -pinchCenter.y);

Now we can update the view with the modified transform:

    pinchView.transform = transform;

Finally, we reset the gesture recognizer's scale, since we've applied the current scale:

    pinch.scale = 1.0;
}

Demo:

pinch scale

Note that in the simulator, you can hold option (alt) for a pinch gesture. Holding shift (while holding option) moves the two touches together.

Here's the code all together for copy/paste:

- (IBAction)pinchGestureDidFire:(UIPinchGestureRecognizer *)pinch {
    UIView *pinchView = pinch.view;
    CGRect bounds = pinchView.bounds;
    CGPoint pinchCenter = [pinch locationInView:pinchView];
    pinchCenter.x -= CGRectGetMidX(bounds);
    pinchCenter.y -= CGRectGetMidY(bounds);
    CGAffineTransform transform = pinchView.transform;
    transform = CGAffineTransformTranslate(transform, pinchCenter.x, pinchCenter.y);
    CGFloat scale = pinch.scale;
    transform = CGAffineTransformScale(transform, scale, scale);
    transform = CGAffineTransformTranslate(transform, -pinchCenter.x, -pinchCenter.y);
    pinchView.transform = transform;
    pinch.scale = 1.0;
}
like image 183
rob mayoff Avatar answered Sep 19 '22 15:09

rob mayoff