Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6767873
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T15:00:12+00:00 2026-05-26T15:00:12+00:00

I have a simple app where I attach a UIPinchGestureRecognizer and UIPanGestureRecognizer to an

  • 0

I have a simple app where I attach a UIPinchGestureRecognizer and UIPanGestureRecognizer to an imageView so I can drag and scale it. I have made it so the imageView can be partially moved off the screen and minimized off the display, but a small 75 pixel part of the image remains on the display so the image can be dragged back onto it. So for instance if I try to drag the imageView off the right part of the display, it will stop when 75 pixels of the imageView is remaining, leaving just enough space for me to drag it back. Same concept with scaling, the boundary frame I create prevents the imageView from being minimized off the display.

Anyhow, I’m having this problem with my boundary code in my UIPinchGestureRecognizer delegate method. The way I’m doing the boundary is I’m creating a frame that is a replica of the imageViews superview – except it’s pushed in 75 pixels on each side and top and bottom. I check to see if the imageView is NOT intersecting with this frame, and then I know it’s reached one of the boundaries on the right / left or top / bottom. It works for the most part, however when I enlarge the image to be quite large (usually somewhere over 1000 by 1000), the boundary doesn’t work – if I do an ultra quick minimize scale, the imageView gets pushed completely off the screen so I can’t drag it back.

I’m just wondering why this is happening. Does it have to do with the image size getting too large? Or is it a flaw in my code? (I’ve listed below). If anyone can help would be appreciated.

- (void)scale:(UIPinchGestureRecognizer *)sender 
{
    if([sender state] == UIGestureRecognizerStateBegan) 
    {
        lastScale = [sender scale];
    }

    if ([sender state] == UIGestureRecognizerStateBegan || 
        [sender state] == UIGestureRecognizerStateChanged) 
    {
        CGFloat currentScale = [[[sender view].layer valueForKeyPath:@"transform.scale"] floatValue];
        CGFloat newScale = 1 -  (lastScale - [sender scale]);// * (CropThePhotoViewControllerPinchSpeed);    
        newScale = MAX(newScale, CropThePhotoViewControllerMinScale / currentScale);

        CGFloat scaledWidth = newScale * sender.view.frame.size.width;
        CGFloat scaledHeight = newScale * sender.view.frame.size.height;

        CGRect translatedRect = CGRectMake(sender.view.frame.origin.x, sender.view.frame.origin.y, scaledWidth, scaledHeight);
        CGRect boundaryRect = CGRectMake(sender.view.superview.frame.origin.x + CropThePhotoViewControllerBoundaryBuffer, sender.view.superview.frame.origin.y + CropThePhotoViewControllerBoundaryBuffer, sender.view.superview.frame.size.width - (CropThePhotoViewControllerBoundaryBuffer * 2), sender.view.superview.frame.size.height - (CropThePhotoViewControllerBoundaryBuffer * 2));

        if (!(!CGRectIntersectsRect(boundaryRect,translatedRect) && newScale < 1))
        {
            CGAffineTransform transform = CGAffineTransformScale([[sender view] transform], newScale, newScale);
            [[sender view] setTransform: transform];
            lastScale = [sender scale];;
        }
    } 
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T15:00:13+00:00Added an answer on May 26, 2026 at 3:00 pm

    I found out what was wrong. For this line of code, I was setting the x and y values incorrectly:

    CGRect translatedRect = CGRectMake(sender.view.frame.origin.x, sender.view.frame.origin.y, scaledWidth, scaledHeight);
    

    It should be:

    CGRect translatedRect = CGRectMake(sender.view.frame.origin.x + (((sender.view.frame.size.width - scaledWidth) / 2)), sender.view.frame.origin.y + (((sender.view.frame.size.height - scaledHeight) / 2)), scaledWidth, scaledHeight);
    

    I wasn’t accounting for the fact that the origin was going to move when the imageview was shrunk.

    I made this change, and actually updated the method to be improved. Now instead of just not performing a scale if the user tries minimizing beyond the boundary, instead I move the imageView right to the border. This is smoother and ultimately better imo. It’s working pretty well after testing, but if anyone sees any bugs please let me know:

    - (void)scale:(UIPinchGestureRecognizer *)sender 
    {
        if([sender state] == UIGestureRecognizerStateBegan) 
        {
            previousScale = [sender scale];
        }
    
    
        if ([sender state] == UIGestureRecognizerStateBegan || 
            [sender state] == UIGestureRecognizerStateChanged) 
        {
            CGFloat nextScale = 1 -  (previousScale - [sender scale]);// * (CropThePhotoViewControllerPinchSpeed); 
    
            nextScale = MAX(nextScale, CropThePhotoViewControllerMinScale / [[[sender view].layer valueForKeyPath:@"transform.scale"] floatValue]);
    
            CGFloat scaledWidth = nextScale * sender.view.frame.size.width;
            CGFloat scaledHeight = nextScale * sender.view.frame.size.height;
            CGFloat currentScale = [sender scale];
    
            CGRect translatedRect = CGRectMake(sender.view.frame.origin.x + (((sender.view.frame.size.width - scaledWidth) / 2)), sender.view.frame.origin.y + (((sender.view.frame.size.height - scaledHeight) / 2)), scaledWidth, scaledHeight);
            CGRect boundaryRect = CGRectMake(sender.view.superview.frame.origin.x + CropThePhotoViewControllerBoundaryBuffer, sender.view.superview.frame.origin.y + CropThePhotoViewControllerBoundaryBuffer, sender.view.superview.frame.size.width - (CropThePhotoViewControllerBoundaryBuffer * 2), sender.view.superview.frame.size.height - (CropThePhotoViewControllerBoundaryBuffer * 2));
    
            if ((!CGRectIntersectsRect(boundaryRect,translatedRect)) && (nextScale < 1))        
            {
                CGFloat leftScaledEdge, rightScaledEdge, topScaledEdge, bottomScaledEdge;
                CGFloat leftBoundary, rightBoundary, topBoundary, bottomBoundary;
                CGFloat nextXScale, nextYScale;
    
                nextXScale = CGFLOAT_MIN;
                nextYScale = CGFLOAT_MIN;
    
                rightScaledEdge = translatedRect.origin.x + translatedRect.size.width;
                leftScaledEdge = translatedRect.origin.x;
                bottomScaledEdge = translatedRect.origin.y + translatedRect.size.height;
                topScaledEdge = translatedRect.origin.y;
    
                leftBoundary = boundaryRect.origin.x;
                rightBoundary = boundaryRect.origin.x + boundaryRect.size.width; 
                topBoundary = boundaryRect.origin.y;
                bottomBoundary = boundaryRect.origin.y + boundaryRect.size.height;  
    
                if (rightScaledEdge < leftBoundary || leftScaledEdge > rightBoundary)
                {
                    if (rightScaledEdge < leftBoundary)
                    {
                        CGFloat adjustedWidth = sender.view.frame.size.width - fabsf((leftBoundary - (sender.view.frame.origin.x + sender.view.frame.size.width)));
                        nextXScale = (nextScale * (adjustedWidth)) / scaledWidth;
                    }
                    else
                    {
                        CGFloat adjustedWidth = sender.view.frame.size.width - fabsf((rightBoundary - sender.view.frame.origin.x));
                        nextXScale = (nextScale * (adjustedWidth)) / scaledWidth;
                    }
                }
    
                if (bottomScaledEdge < topBoundary || topScaledEdge > bottomBoundary)
                {
                    if (bottomScaledEdge < topBoundary)
                    {
                        CGFloat adjustedHeight = sender.view.frame.size.height - fabsf((topBoundary - (sender.view.frame.origin.y + sender.view.frame.size.height)));
                        nextYScale = (nextScale * (adjustedHeight)) / scaledHeight;
                    }
                    else
                    {
                        CGFloat adjustedHeight = sender.view.frame.size.height - fabsf((bottomBoundary - sender.view.frame.origin.y));
                        nextYScale = (nextScale * (adjustedHeight)) / scaledHeight;
    
                    }
                }
    
                if (nextXScale >= nextYScale)
                {
                    nextScale = nextXScale;
                }
                else 
                {
                    nextScale = nextYScale;
                }
    
                currentScale = nextScale - 1 + previousScale;
            }
    
            CGAffineTransform transform = CGAffineTransformScale([[sender view] transform], nextScale, nextScale);
            [[sender view] setTransform: transform];
            previousScale = currentScale;
        } 
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a simple app with a full screen UIWebView. This contains HTML generated
This is a real newbie question. I have simple app that selects a picture
I have a simple app that uses an SQL Express 2005 database. When the
Right so I have a simple app that consists of a calendar a Set
I'm now testing GKPeerPickerController. I have a simple app that just have a button
I have a simple iphone app that's based on the CrashLanding sample app. So
I have a simple Google App Engine app, that I wrote using ordinary strings.
I have created some simple app in Java, and 'deployed' it using Java Web
I have a simple cakephp app with table articles that has a cat_id column
I have done simple java app for blackberry, while building am getting following error.

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.