Pinch Zoom using UIPinchGestureRecognizer Tutorial


After seeing many pinch zoom samples I am unhappy, most of samples show only how to use UIPinchGestureRecognizer but none of sample tell how to continue apply pinch zoom from where it left. In this sample I tried to support pinch zoom from where it left.


Before Zoom

After Zoom
Creating UIPinchGestureRecognizer  And adding To Pich View.

UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(handlePinch:)];
[mGestureView addGestureRecognizer:pinchGesture];
    [pinchGesture release];

Heare mGestureView is UIView on which we adding UIPinchGestureRecognizer instance

Handling Pinch Zoom

-(void)handlePinch:(UIPinchGestureRecognizer*)sender {
        
    /*
     There are different actions to take for the different states of the gesture recognizer.
     * In the Began state, use the pinch location to find the index path of the row with which the pinch is associated, and keep a reference to that in pinchedIndexPath. Then get the current height of that row, and store as the initial pinch height. Finally, update the scale for the pinched row.
     * In the Changed state, update the scale for the pinched row (identified by pinchedIndexPath).
     * In the Ended or Canceled state, set the pinchedIndexPath property to nil.
     */
         NSLog(@"latscale = %f",mLastScale);

         mCurrentScale += [sender scale] - mLastScale;
         mLastScale = [sender scale];
        
         if (sender.state == UIGestureRecognizerStateEnded)
         {
                  mLastScale = 1.0;
         }
        
         CGAffineTransform currentTransform = CGAffineTransformIdentity;
         CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, mCurrentScale, mCurrentScale);
         mGestureView.transform = newTransform;
        
}

The logic here is simple first we getting current  scale value.

mCurrentScale += [sender scale] - mLastScale;

we are minusing it with previos pinch only to get current zoom. And once user lifts finger we are reseting lastscale value to 0.0 (i.e UIPinchGestureRecognizer values start from 1.0 actual zoom ) in UIGestureRecognizerStateEnded.

Lastly we applying CGAffineTransformScale to view to zoom.

CGAffineTransform currentTransform = CGAffineTransformIdentity;
         CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, mCurrentScale, mCurrentScale);
    mGestureView.transform = newTransform;


Note:
One more nice and full coverage tutorial about UIGestureRecognize is return by Raywanderlich
click here to Read Tutorial.




20 comments:

  1. Jesus Christ.... remove some of the damn popups...

    ReplyDelete
  2. popups are an extreme overkill. really gives this blog a cheap warez site feel. even though the content is good, I think I will try to avoid this blog from now on.

    ReplyDelete
  3. I hope that Hell doesn't have popups like these

    ReplyDelete
  4. Ad Block Plus?

    ReplyDelete
  5. Max ONE popup PLEASE!!!!!

    ReplyDelete
  6. what is value of mLasttScale and current scale?

    ReplyDelete
  7. Damn pop ups... Took me over 1 minute to finally figure out how to enter your site.

    ReplyDelete
  8. Oh my .... This is the last time I enter this site. It reminds me of a virus infected PC popup nightmare!

    ReplyDelete
  9. Can i get xcode project of this?

    ReplyDelete
  10. Sample Xcode project uploaded ... Pop up removed.

    ReplyDelete
  11. Great sample.........

    ReplyDelete
  12. Superb smaple
    Thanks dear :)

    ReplyDelete
  13. Very Nice sample :)

    Nikki

    ReplyDelete
  14. Thank you. it works well.

    ReplyDelete
  15. Thanks for your article - it helped me a lot.
    There's a bug though - you can't add scales, you have to multiply them.
    Your code does work somehow, but the zoom is not right in some cases.
    The proper way is actually even simpler:

    -(void)handlePinch:(UIPinchGestureRecognizer*)sender {
    mScale = sender.scale*mLastScale;
    if (sender.state == UIGestureRecognizerStateEnded) mLastScale = mScale;

    CGAffineTransform currentTransform = CGAffineTransformIdentity;
    CGAffineTransform newTransform = CGAffineTransformScale(currentTransform, mScale,mScale);
    view.transform = newTransform;
    }

    ( and you have to set the mLastScale to 1 somewhere in your init)

    ReplyDelete
    Replies
    1. Much cleaner code would be,

      -(void)handlePinch:(UIPinchGestureRecognizer*)sender {
      recognizer.view.transform = CGAffineTransformScale(recognizer.view.transform, recognizer.scale, recognizer.scale);
      recognizer.scale = 1;
      }

      Delete
  16. Your student loans people plan should do the same with the whole
    advertising process. These conditions result
    from chronic muscle strain caused by holding your body in an upright position,
    tilt your head to the left side of the business, instead of going straight to the hard sell.



    my webpage youngbusiness.info

    ReplyDelete
  17. Being surrounded by renowned schools including Cedar Primary School, Maris Stella High School
    (Primary), and the St. Andrew's Village suite of Kindergarten to Junior College education. the interlace condo

    ReplyDelete
  18. The pop up is my fetish

    ReplyDelete