Pinch zoom shifting image to most left corner on iPad in iOS? Pinch zoom shifting image to most left corner on iPad in iOS? objective-c objective-c

Pinch zoom shifting image to most left corner on iPad in iOS?


Here is a possible solution.

• I've renamed your zoom_image by contentView, because this class can manipulate any view, not only images.

• I've removed the bound tests, and let the scale be in ( 0.01 - 10.0 )

• The pinch handle up to three fingers, and also acts as pan. Number of touches can be changed without interrupting the pinch.

There is still many things to improve, but the main principle is here :)

Interface ( properties like minScale,maxScale, minMargin and so are still to be added - why not a delegate )

@interface PinchViewController : UIViewController@property(nonatomic,strong) IBOutlet UIView* contentView;@end

Implementation

@implementation PinchViewController{    CGPoint translation;    CGFloat scale;    CGAffineTransform scaleTransform;    CGAffineTransform translateTransform;    CGPoint     previousTranslation;    CGFloat     previousScale;    NSUInteger  previousNumTouches;}-(void)viewDidLoad{    scale = 1.0f;    scaleTransform = CGAffineTransformIdentity;    translateTransform = CGAffineTransformIdentity;    previousTranslation = CGPointZero;    previousNumTouches = 0;    UIPinchGestureRecognizer *pinch=[[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(handlePinch:)];    [self.view addGestureRecognizer:pinch];    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)];    [panGesture setMinimumNumberOfTouches:1];    [panGesture setMaximumNumberOfTouches:1];    [self.view addGestureRecognizer:panGesture];}-(void)handlePinch:(UIPinchGestureRecognizer*)recognizer{    // 1 - find pinch center    CGPoint mid = [self computePinchCenter:recognizer];    mid.x-= recognizer.view.bounds.size.width / 2.0f;    mid.y-= recognizer.view.bounds.size.height / 2.0f;    // 2 - compute deltas    NSUInteger numTouches = recognizer.numberOfTouches;    if ( (recognizer.state==UIGestureRecognizerStateBegan)  || ( previousNumTouches != numTouches ) ) {        previousScale = recognizer.scale;        previousTranslation = mid;        previousNumTouches = numTouches;    }    CGFloat deltaScale = ( recognizer.scale - previousScale ) * scale;    previousScale = recognizer.scale;    CGPoint deltaTranslation = CGPointMake(mid.x-previousTranslation.x, mid.y-previousTranslation.y);    previousTranslation = mid;    deltaTranslation.x/=scale;    deltaTranslation.y/=scale;    // 3 - apply    scale+=deltaScale;    if (scale<0.01) scale = 0.01; else if (scale>10) scale = 10;    scaleTransform = CGAffineTransformMakeScale(scale, scale);    [self translateBy:deltaTranslation];    NSLog(@"Translation : %.2f,%.2f - Scale Center : %.2f,%.2f - Scale : %.2f",deltaTranslation.x,deltaTranslation.y,mid.x,mid.y,scale);}- (void)handlePan:(UIPanGestureRecognizer *)recognizer{    if (recognizer.state==UIGestureRecognizerStateBegan) previousTranslation = CGPointZero;    CGPoint recognizerTranslation = [recognizer translationInView:self.contentView];    CGPoint deltaTranslation = CGPointMake(recognizerTranslation.x - previousTranslation.x,recognizerTranslation.y - previousTranslation.y);    previousTranslation = recognizerTranslation;    [self translateBy:deltaTranslation];    NSLog(@"Translation : %.2f,%.2f - Scale : %.2f",deltaTranslation.x,deltaTranslation.y,scale);}-(void)translateBy:(CGPoint)delta{    translation.x+=delta.x;    translation.y+=delta.y;    translateTransform = CGAffineTransformMakeTranslation(translation.x,translation.y);    self.contentView.transform = CGAffineTransformConcat(translateTransform,scaleTransform);}-(CGPoint)computePinchCenter:(UIPinchGestureRecognizer*)recognizer{    // 1 - handle up to 3 touches    NSUInteger numTouches = recognizer.numberOfTouches;    if (numTouches>3) numTouches = 3;    // 2 - Find fingers middle point - with (0,0) being the center of the view    CGPoint pt1,pt2,pt3,mid;    switch (numTouches) {        case 3:            pt3 = [recognizer locationOfTouch:2 inView:recognizer.view];        case 2:            pt2 = [recognizer locationOfTouch:1 inView:recognizer.view];        case 1:            pt1 = [recognizer locationOfTouch:0 inView:recognizer.view];    }    switch (numTouches) {        case 3:            mid = CGPointMake( ( ( pt1.x + pt2.x ) / 2.0f + pt3.x ) / 2.0f, ( ( pt1.y + pt2.y ) / 2.0f + pt3.y ) / 2.0f );            break;        case 2:            mid = CGPointMake( ( pt1.x + pt2.x ) / 2.0f, ( pt1.y + pt2.y ) / 2.0f  );            break;        case 1:            mid = CGPointMake( pt1.x, pt1.y);            break;    }    return mid;}@end

Hope it will help :) Cheers