如何在没有 UIScrollView 的情况下放大和缩小 UIImageView?

发布于 2024-11-08 02:32:19 字数 5460 浏览 8 评论 0原文

我正在为 iOS 4.2 iPhone 开发一个应用程序,在这个应用程序中我下载图像并将它们保存在内部存储(NSDocuments)中。

好吧,然后我在 UIImageView 中显示第一张图像。用户可以在 UIImageView (TouchesMoved) 上拖动手指,当用户这样做时,我会加载其他图像。如果用户向下拖动,我会加载一张图像,如果向上拖动,我会加载其他图像,并且还会加载左右图像。

这一切都完成了。但我想实现缩放。到目前为止,这是我的代码:

initialDistance -->是第一次触摸时手指之间的距离
最终距离 -->是每次移动手指之间的距离
x-->是 0
y -->是 0

    // this method calculate the distance between 2 fingers
    - (CGFloat)distanceBetweenTwoPoints:(CGPoint)fromPoint toPoint:(CGPoint)toPoint {
        float xPoint = toPoint.x - fromPoint.x;
        float yPoint = toPoint.y - fromPoint.y;

        return sqrt(xPoint * xPoint + yPoint * yPoint);
     }

        //------------------- Movimientos con los dedos ------------------------------------
        #pragma mark -
        #pragma mark UIResponder

          // First Touch
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

NSSet *allTouches = [event allTouches];

switch ([allTouches count]) {
    case 1: { //Single touch

        //Get the first touch.
        UITouch *touch1 = [[allTouches allObjects] objectAtIndex:0];

        switch ([touch1 tapCount])
        {
            case 1: //Single Tap.
            {
                // Guardo la primera localización del dedo cuando pulsa por primera vez
                //inicial = [touch1 locationInView:self.view];

            } break;
            case 2: {//Double tap. 
                //Track the initial distance between two fingers.
                //if ([[allTouches allObjects] count] >= 2) {

                // oculto/o no, la barra de arriba cuando se hace un dobleTap
                //[self switchToolBar];

            } break;
        }
    } break;
    case 2: { //Double Touch

        // calculo la distancia inicial que hay entre los dedos cuando empieza a tocar
        UITouch *touch1 = [[allTouches allObjects] objectAtIndex:0];
        UITouch *touch2 = [[allTouches allObjects] objectAtIndex:1];

        initialDistance = [self distanceBetweenTwoPoints:[touch1 locationInView:[self view]]
                                                 toPoint:[touch2 locationInView:[self view]]];
    }
    default:
        break;
}
}

// when the finger/s move to 
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{

NSSet *allTouches = [event allTouches];

switch ([allTouches count])
{
    case 1: {



    } break;
    case 2: {
        //The image is being zoomed in or out.

        UITouch *touch1 = [[allTouches allObjects] objectAtIndex:0];
        UITouch *touch2 = [[allTouches allObjects] objectAtIndex:1];

        //Calculate the distance between the two fingers.
        CGFloat finalDistance = [self distanceBetweenTwoPoints:[touch1 locationInView:[self view]]
                                                       toPoint:[touch2 locationInView:[self view]]];

        NSLog(@"Distancia Inicial :: %.f, Ditancia final :: %.f", initialDistance, finalDistance);

        float factorX = 20.0;
        float factorY = 11.0;

        // guardo la posicion de los 2 dedos
        //CGPoint dedo1 = [[[touches allObjects] objectAtIndex:0] locationInView:self.view];
        //CGPoint dedo2 = [[[touches allObjects] objectAtIndex:1] locationInView:self.view];

        // comparo para saber si el usuario esta haciendo zoom in o zoom out
        if(initialDistance < finalDistance) {
            NSLog(@"Zoom In");

            float newWidth = imagen.frame.size.width + (initialDistance - finalDistance + factorX);
            float newHeight = imagen.frame.size.height + (initialDistance - finalDistance + factorY);

            if (newWidth <= 960 && newHeight <= 640) {
                /*
                 if (dedo1.x >= dedo2.x) {
                 x = (dedo1.x + finalDistance/2); 
                 y = (dedo1.y + finalDistance/2);
                 } else {
                 x = (dedo2.x + finalDistance/2); 
                 y = (dedo2.y + finalDistance/2);
                 }
                 */

                //x = (dedo1.x);
                //y = (dedo1.y);

                imagen.frame = CGRectMake( x, y, newWidth, newHeight);
            } else {
                imagen.frame = CGRectMake( x, y, 960, 640);
            }



        }
        else {
            NSLog(@"Zoom Out");

            float newWidth = imagen.frame.size.width - (finalDistance - initialDistance + factorX);
            float newHeight = imagen.frame.size.height - (finalDistance - initialDistance + factorY);

            if (newWidth >= 480 && newHeight >= 320) { 
                /*
                 if (dedo1.x >= dedo2.x) {
                 x = (dedo1.x + finalDistance/2); 
                 y = (dedo1.y + finalDistance/2);
                 } else {
                 x = (dedo2.x + finalDistance/2); 
                 y = (dedo2.y + finalDistance/2);
                 }
                 */
                //x -= (finalDistance - initialDistance + factorX); 
                //y -= (finalDistance - initialDistance + factorX); 

                //x = (dedo1.x);
                //y = (dedo1.y);

                imagen.frame = CGRectMake( x, y, newWidth, newHeight);
            } else {
                imagen.frame = CGRectMake( 0, 0, 480, 320);
            }



        }

        initialDistance = finalDistance;

    } break;
}
}

#pragma mark -

非常感谢!

PD:如果 UIScrollView 有一种可以在不同图像之间移动的方法,我也愿意看一下。

I'm developing an app for iOS 4.2, iPhone, in this app I download images and I save them in the internal storage (NSDocuments).

Well, then I show the first image in a UIImageView. The user can drag their finger on the UIImageView (TouchesMoved), when the user do that, I load other image. If the user drag down, I load one image, if drag up, i load other, and also with right and left.

This is all done. But I want to implement zooming. This is my code until now:

initialDistance --> is the distance between the fingers at first touch
finalDistance --> is the distance between the fingers each time they move
x --> is 0
y --> is 0

    // this method calculate the distance between 2 fingers
    - (CGFloat)distanceBetweenTwoPoints:(CGPoint)fromPoint toPoint:(CGPoint)toPoint {
        float xPoint = toPoint.x - fromPoint.x;
        float yPoint = toPoint.y - fromPoint.y;

        return sqrt(xPoint * xPoint + yPoint * yPoint);
     }

        //------------------- Movimientos con los dedos ------------------------------------
        #pragma mark -
        #pragma mark UIResponder

          // First Touch
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

NSSet *allTouches = [event allTouches];

switch ([allTouches count]) {
    case 1: { //Single touch

        //Get the first touch.
        UITouch *touch1 = [[allTouches allObjects] objectAtIndex:0];

        switch ([touch1 tapCount])
        {
            case 1: //Single Tap.
            {
                // Guardo la primera localización del dedo cuando pulsa por primera vez
                //inicial = [touch1 locationInView:self.view];

            } break;
            case 2: {//Double tap. 
                //Track the initial distance between two fingers.
                //if ([[allTouches allObjects] count] >= 2) {

                // oculto/o no, la barra de arriba cuando se hace un dobleTap
                //[self switchToolBar];

            } break;
        }
    } break;
    case 2: { //Double Touch

        // calculo la distancia inicial que hay entre los dedos cuando empieza a tocar
        UITouch *touch1 = [[allTouches allObjects] objectAtIndex:0];
        UITouch *touch2 = [[allTouches allObjects] objectAtIndex:1];

        initialDistance = [self distanceBetweenTwoPoints:[touch1 locationInView:[self view]]
                                                 toPoint:[touch2 locationInView:[self view]]];
    }
    default:
        break;
}
}

// when the finger/s move to 
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{

NSSet *allTouches = [event allTouches];

switch ([allTouches count])
{
    case 1: {



    } break;
    case 2: {
        //The image is being zoomed in or out.

        UITouch *touch1 = [[allTouches allObjects] objectAtIndex:0];
        UITouch *touch2 = [[allTouches allObjects] objectAtIndex:1];

        //Calculate the distance between the two fingers.
        CGFloat finalDistance = [self distanceBetweenTwoPoints:[touch1 locationInView:[self view]]
                                                       toPoint:[touch2 locationInView:[self view]]];

        NSLog(@"Distancia Inicial :: %.f, Ditancia final :: %.f", initialDistance, finalDistance);

        float factorX = 20.0;
        float factorY = 11.0;

        // guardo la posicion de los 2 dedos
        //CGPoint dedo1 = [[[touches allObjects] objectAtIndex:0] locationInView:self.view];
        //CGPoint dedo2 = [[[touches allObjects] objectAtIndex:1] locationInView:self.view];

        // comparo para saber si el usuario esta haciendo zoom in o zoom out
        if(initialDistance < finalDistance) {
            NSLog(@"Zoom In");

            float newWidth = imagen.frame.size.width + (initialDistance - finalDistance + factorX);
            float newHeight = imagen.frame.size.height + (initialDistance - finalDistance + factorY);

            if (newWidth <= 960 && newHeight <= 640) {
                /*
                 if (dedo1.x >= dedo2.x) {
                 x = (dedo1.x + finalDistance/2); 
                 y = (dedo1.y + finalDistance/2);
                 } else {
                 x = (dedo2.x + finalDistance/2); 
                 y = (dedo2.y + finalDistance/2);
                 }
                 */

                //x = (dedo1.x);
                //y = (dedo1.y);

                imagen.frame = CGRectMake( x, y, newWidth, newHeight);
            } else {
                imagen.frame = CGRectMake( x, y, 960, 640);
            }



        }
        else {
            NSLog(@"Zoom Out");

            float newWidth = imagen.frame.size.width - (finalDistance - initialDistance + factorX);
            float newHeight = imagen.frame.size.height - (finalDistance - initialDistance + factorY);

            if (newWidth >= 480 && newHeight >= 320) { 
                /*
                 if (dedo1.x >= dedo2.x) {
                 x = (dedo1.x + finalDistance/2); 
                 y = (dedo1.y + finalDistance/2);
                 } else {
                 x = (dedo2.x + finalDistance/2); 
                 y = (dedo2.y + finalDistance/2);
                 }
                 */
                //x -= (finalDistance - initialDistance + factorX); 
                //y -= (finalDistance - initialDistance + factorX); 

                //x = (dedo1.x);
                //y = (dedo1.y);

                imagen.frame = CGRectMake( x, y, newWidth, newHeight);
            } else {
                imagen.frame = CGRectMake( 0, 0, 480, 320);
            }



        }

        initialDistance = finalDistance;

    } break;
}
}

#pragma mark -

Thank you very much!!

PD: If there is a method with UIScrollView whitch I can move between different images, I m open to take a look too.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

最丧也最甜 2024-11-15 02:32:19

好的。如果只是为了实现缩放功能,您可以考虑使用 UIScrollView。

假设我们有一个 scrollView 和一个 imageView ,两者都有相同的边界。添加imageView作为scrollView的子视图。

[scrollView addSubview:imageView];
scrollView.contentSize = imageView.frame.size;

要在 scrollView 中仅支持缩放而不支持平移,您的 viewController 必须采用 UIScrollViewDelegate 协议。

// Disabling panning/scrolling in the scrollView
scrollView.scrollEnabled = NO;

// For supporting zoom,
scrollView.minimumZoomScale = 0.5;
scrollView.maximumZoomScale = 2.0;

...

// Implement a single scroll view delegate method
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)aScrollView {
    return imageView;
}

现在我们已经可以使用缩放功能了。对于滑动,您可以使用适当配置的 UISwipeGestureRecognizers。创建一个手势来处理每个滑动方向并将其添加到滚动视图。

UISwipeGestureRecognizer *rightSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self selector:@selector(handleRightSwipe:)];
rightSwipe.direction = UISwipeGestureRecognizerDirectionRight;
rightSwipe.numberOfTouchesRequired = 1;
[scrollView addGesture:rightSwipe];
[rightSwipe release];

并根据手势检索适当的图像并使用imageView.image = yourImage;进行设置。

Ok. You can consider using a UIScrollView if only to use it for its zoom functionality.

Say we have a scrollView and a imageView with both having the same bounds. Add the imageView as the subview of scrollView.

[scrollView addSubview:imageView];
scrollView.contentSize = imageView.frame.size;

To support only zoom and not not panning in the scrollView your viewController will have to adopt the UIScrollViewDelegate protocol.

// Disabling panning/scrolling in the scrollView
scrollView.scrollEnabled = NO;

// For supporting zoom,
scrollView.minimumZoomScale = 0.5;
scrollView.maximumZoomScale = 2.0;

...

// Implement a single scroll view delegate method
- (UIView*)viewForZoomingInScrollView:(UIScrollView *)aScrollView {
    return imageView;
}

By now we have zooming available. For swipes, you can use appropriately configured UISwipeGestureRecognizers. Create a gesture for handling each swipe direction and add it to scroll view.

UISwipeGestureRecognizer *rightSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self selector:@selector(handleRightSwipe:)];
rightSwipe.direction = UISwipeGestureRecognizerDirectionRight;
rightSwipe.numberOfTouchesRequired = 1;
[scrollView addGesture:rightSwipe];
[rightSwipe release];

And retrieve the appropriate image based on the gesture and set it using imageView.image = yourImage;.

寻梦旅人 2024-11-15 02:32:19

最后,在Deepak的帮助下,我使用UIImageView的transform属性来进行缩放。

我在 CGAffineTransform 矩阵中的位置 [0,0] 处使用 CGFloat 来设置限制。我必须在放大时将 CGFloat 传递给字符串,因为当我将它与 0 进行比较时,这始终是正确的。

最后,这是我在 TouchesMoved 中的代码,如果它对某人有用的话:

// comparo para saber si el usuario esta haciendo zoom in o zoom out
        if(initialDistance < finalDistance) {
            NSLog(@"Zoom Out");

            CGAffineTransform transformer = CGAffineTransformScale(imagen.transform, 1.05, 1.05);

            NSLog(@"transformer :: A: %.f, B: %.f, C: %.f, D: %.f", imagen.transform.a, imagen.transform.b, imagen.transform.c, imagen.transform.d);

            if (transformer.a < 5) {
                [UIView beginAnimations:nil context:NULL];
                [UIView setAnimationDuration: 0.2];
                imagen.transform = transformer;
                [UIView setAnimationDelegate:self];
                [UIView commitAnimations];
            }
        }
        else {
            NSLog(@"Zoom In");

            CGAffineTransform transformer = CGAffineTransformScale(imagen.transform, 0.95, 0.95);

            NSLog(@"transformer :: A: %.f, B: %.f, C: %.f, D: %.f", transformer.a, transformer.b, transformer.c, transformer.d);

            NSString *num = [NSString stringWithFormat:@"%.f", transformer.a];

            if (![num isEqualToString:@"0"]) {
                [UIView beginAnimations:nil context:NULL];
                [UIView setAnimationDuration: 0.2];
                imagen.transform = transformer;
                [UIView setAnimationDelegate:self];
                [UIView commitAnimations];
            }
        }

当然,非常感谢 Deepak。

Finally, with Deepak's help, I use the transform property of UIImageView to make the Zooming.

I use the CGFloat at the position [0,0] in the matrix of the CGAffineTransform to set the limits. I have to pass the CGFloat to a string at zoom in because when i compare it with 0 this is always true.

Finally this is my code in touchesMoved, if it's useful for someone:

// comparo para saber si el usuario esta haciendo zoom in o zoom out
        if(initialDistance < finalDistance) {
            NSLog(@"Zoom Out");

            CGAffineTransform transformer = CGAffineTransformScale(imagen.transform, 1.05, 1.05);

            NSLog(@"transformer :: A: %.f, B: %.f, C: %.f, D: %.f", imagen.transform.a, imagen.transform.b, imagen.transform.c, imagen.transform.d);

            if (transformer.a < 5) {
                [UIView beginAnimations:nil context:NULL];
                [UIView setAnimationDuration: 0.2];
                imagen.transform = transformer;
                [UIView setAnimationDelegate:self];
                [UIView commitAnimations];
            }
        }
        else {
            NSLog(@"Zoom In");

            CGAffineTransform transformer = CGAffineTransformScale(imagen.transform, 0.95, 0.95);

            NSLog(@"transformer :: A: %.f, B: %.f, C: %.f, D: %.f", transformer.a, transformer.b, transformer.c, transformer.d);

            NSString *num = [NSString stringWithFormat:@"%.f", transformer.a];

            if (![num isEqualToString:@"0"]) {
                [UIView beginAnimations:nil context:NULL];
                [UIView setAnimationDuration: 0.2];
                imagen.transform = transformer;
                [UIView setAnimationDelegate:self];
                [UIView commitAnimations];
            }
        }

And of course, a lot of thanks to Deepak.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文