TechChain
TechChain

Reputation: 8944

how to stop moving image when image is not zoomed in?

I have a UIImageView i am performing pinch zoom & move image on full zoom.I am able to move the image but the issue is even if the image is not zoomed in it still moves on the screen.Please tell me how can i prevent it?

Here is the code for that

#define MINIMUM_SCALE 0.5
#define MAXIMUM_SCALE 6.0
@property CGPoint translation;


- (void)pan:(UIPanGestureRecognizer *)gesture {
    static CGPoint currentTranslation;
    static CGFloat currentScale = 0;
    if (gesture.state == UIGestureRecognizerStateBegan) {
        currentTranslation = _translation;
        currentScale = self.view.frame.size.width / self.view.bounds.size.width;
    }
    if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateChanged) {

        CGPoint translation = [gesture translationInView:self.view];

        _translation.x = translation.x + currentTranslation.x;
        _translation.y = translation.y + currentTranslation.y;
        CGAffineTransform transform1 = CGAffineTransformMakeTranslation(_translation.x , _translation.y);
        CGAffineTransform transform2 = CGAffineTransformMakeScale(currentScale, currentScale);
        CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2);
        self.view.transform = transform;
    }
}


- (void)pinch:(UIPinchGestureRecognizer *)gesture {
    if (gesture.state == UIGestureRecognizerStateEnded || gesture.state == UIGestureRecognizerStateChanged) {
//        NSLog(@"gesture.scale = %f", gesture.scale);

        CGFloat currentScale = self.view.frame.size.width / self.view.bounds.size.width;
        CGFloat newScale = currentScale * gesture.scale;

        if (newScale < MINIMUM_SCALE) {
            newScale = MINIMUM_SCALE;
        }
        if (newScale > MAXIMUM_SCALE) {
            newScale = MAXIMUM_SCALE;
        }

        CGAffineTransform transform1 = CGAffineTransformMakeTranslation(_translation.x, _translation.y);
        CGAffineTransform transform2 = CGAffineTransformMakeScale(newScale, newScale);
        CGAffineTransform transform = CGAffineTransformConcat(transform1, transform2);
        self.view.transform = transform;
        gesture.scale = 1;
    }
}

**PS:**ImageView should only move when image is zoomed otherwise it should not be moveable.

Upvotes: 1

Views: 775

Answers (3)

MarkHim
MarkHim

Reputation: 5766

I suggest a different approach:

Create a UIScrollView add the UIImageView into the scrollView's contentView and allow scrolling and zooming on the scrollView.

To prevent scrolling when not zoomed, set setScrollEnabled to NO and enable it in scrollViewDidZoom if the zoomLevel reaches a custom threshold.

So sth. like this should make make it much easier what you're trying to accomplish with a lot less code.

- (void)viewDidLoad:(BOOL)animated {
    [super viewDidLoad:animated];
    self.scrollView.scrollEnabled = NO;
    self.scrollView.minimumZoomScale = 1;
}

- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
    if (scrollView.zoomLevel > 1) {
        scrollView.scrollEnabled = YES;
    } else {
        scrollView.scrollEnabled = NO;
    }
}

Upvotes: 4

Abhishek
Abhishek

Reputation: 509

You can check the frame of your imageView and if it is same it means imageview has not been zoomed So you can disable the pan gesture if frame of imageview is same ......and if frame has changed then you can enable the pan gesture.....

Upvotes: 1

Moose
Moose

Reputation: 2737

I re-post the code I gave you in your first question on the subject ( Pinch zoom shifting image to most left corner on iPad in iOS? ), because I think the way you do it does not work as expected ( as far as I have tested ).

The pinch zoom is supposed to zoom on the middle of the fingers, and not on the middle of the image. If you really want to apply the zoom on center, I have added a boolean property zoomOnCenter.

The boundaries checking is done in the translateBy method.

Here is a link on the xCode test project: https://drive.google.com/file/d/0B88aMtNA0z2aWVBIbGZGdVhpdWM/view?usp=sharing

Interface

@interface PinchViewController : UIViewController

@property(nonatomic,strong) IBOutlet UIView* contentView;
@property(nonatomic,assign) BOOL zoomOnCenter;

@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.zoomOnCenter ? CGPointZero : [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];
}

- (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];
}


-(void)translateBy:(CGPoint)delta
{
    CGSize contentSize = self.contentView.bounds.size;
    CGSize viewSize = self.view.bounds.size;
    CGSize  scaledViewSize = viewSize;
    scaledViewSize.width/=scale;
    scaledViewSize.height/=scale;
    CGPoint maxTranslation = CGPointMake( (contentSize.width-scaledViewSize.width) / 2.0f , (contentSize.height-scaledViewSize.height) / 2.0f );

    if ( contentSize.width*scale < viewSize.width ) {
        delta.x=0;
        translation.x = 0;
    } else {
        translation.x+=delta.x;
        if ( translation.x < - maxTranslation.x ) {
            translation.x = - maxTranslation.x;
        }
        else if ( translation.x > maxTranslation.x ) {
            translation.x = maxTranslation.x;
        }
    }

    if ( contentSize.height*scale < viewSize.height ) {
        delta.y=0; translation.y = 0;
    } else {
        translation.y+=delta.y;
        if ( translation.y < - maxTranslation.y ) {
            translation.y = - maxTranslation.y;
        }
        else if ( translation.y > maxTranslation.y ) {
            translation.y = maxTranslation.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

Upvotes: 1

Related Questions