Pinch To Zoom Effect on UIImageView inside scrollV

2019-01-14 07:49发布

I'm using storyboard (iOS 6.0) to create a photo gallery viewer for my app. This is how my imageViewController is set up in storyboard:

enter image description here

I've made sure to enable userInteraction and multiple touches on both the imageView and scrollView. What I want to do is, on pinch I want to zoom into the imageView (maximum scale 3) and be able to pan around. This is what I currently have, however, even though the pinch gesture is detected the scale does not change.

- (IBAction)imagePinched:(id)sender {

if (pinchRecognizer.state == UIGestureRecognizerStateEnded || pinchRecognizer.state == UIGestureRecognizerStateChanged) {

    NSLog(@"gesture.scale = %f", pinchRecognizer.scale);

    CGFloat currentScale = self.fullScreenView.frame.size.width / self.fullScreenView.bounds.size.width;
    CGFloat newScale = currentScale * pinchRecognizer.scale;

    if (newScale < 1) {
        newScale = 1;
    }
    if (newScale > 3) {
        newScale = 3;
    }

    CGAffineTransform transform = CGAffineTransformMakeScale(newScale, newScale);
        self.fullScreenView.transform = transform;
        pinchRecognizer.scale = 1;
    }

}

Most questions and tutorials online deal with programmatically creating the views and doing this, but the less code the better (in my eyes). What's the best way to get this to work with storyboard? Thank you in advance!!!


UPDATED:

Here is my full .m file code:

- (void)viewDidLoad
{
    [super viewDidLoad];

    //Assign an image to this controller's imageView
    fullScreenView.image = [UIImage imageNamed:imageString];

    //Allows single and double tap to work
    [singleTapRecognizer requireGestureRecognizerToFail: doubleTapRecognizer];
}

- (IBAction)imageTapped:(id)sender {

    NSLog(@"Image Tapped.");

    //On tap, fade out viewController like the twitter.app
    [self dismissViewControllerAnimated:YES completion:nil];
}

- (IBAction)imageDoubleTapped:(id)sender {

    NSLog(@"Image Double Tapped.");

    //On double tap zoom into imageView to fill in the screen.
    [fullScreenView setContentMode:UIViewContentModeScaleAspectFill];
}

- (IBAction)imagePinched:(id)sender {

    if (pinchRecognizer.state == UIGestureRecognizerStateEnded || pinchRecognizer.state == UIGestureRecognizerStateChanged) {

        NSLog(@"gesture.scale = %f", pinchRecognizer.scale);

        CGFloat currentScale = self.fullScreenView.frame.size.width / self.fullScreenView.bounds.size.width;
        CGFloat newScale = currentScale * pinchRecognizer.scale;

        if (newScale < 1) {
            newScale = 1;
        }
        if (newScale > 3) {
            newScale = 3;
        }

        CGAffineTransform transform = CGAffineTransformMakeScale(newScale, newScale);
        self.fullScreenView.transform = transform;
        pinchRecognizer.scale = 1;
    }
}

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return self.fullScreenView;
}


-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

6条回答
走好不送
2楼-- · 2019-01-14 08:01

You need to do what Wadi suggested above but also set the setMinimumZoomScale to be different from setMaximumZoomScale. They are both 1.0f by default.

After that, the UIImageView should be pinchable

查看更多
迷人小祖宗
3楼-- · 2019-01-14 08:04

I have created a fully working demo application (similar in nature to Facebook's default photo gallery) which demonstrates pinch to zoom of Image View nested inside a scroll view with AutoLayout and storyboards. View my project here: http://rexstjohn.com/facebook-like-ios-photo-modal-gallery-swipe-gestures/.

It also includes async photo loading via MKNetworkKit and gesture based swiping through a photo gallery. Enjoy and I hope it saves everyone time trying to figure this out because it is somewhat annoying.

查看更多
姐就是有狂的资本
4楼-- · 2019-01-14 08:09

Here is how Apple recomends to do what you want to do. I used the code provided by Apple and it worked like a charm! If you want to optimize memory management, you can use iCarousel (made by nicklockwood), which have a cache management for dealloc unused views!

查看更多
神经病院院长
5楼-- · 2019-01-14 08:10

I think better solution in Apple Documentation

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView

{

    return self.imageView;

}
- (void)viewDidLoad {

    [super viewDidLoad];

    self.scrollView.minimumZoomScale=0.5;

    self.scrollView.maximumZoomScale=6.0;

    self.scrollView.contentSize=CGSizeMake(1280, 960);

    self.scrollView.delegate=self;

}

Check Apple Documentation

查看更多
老娘就宠你
6楼-- · 2019-01-14 08:11

I've created a class to handle zooming of UIImageViews similar to Instagram. Might be what you're looking for, otherwise you can look at how I achieved it. https://github.com/twomedia/TMImageZoom

查看更多
Bombasti
7楼-- · 2019-01-14 08:16

The first step is to make sure your views have the correct delegates implemented. For example in the .m file

@interface myRootViewController () <.., UIGestureRecognizerDelegate, UIScrollViewDelegate, ...>

From the documentation, make sure you have this implemented:

The UIScrollView class can have a delegate that must adopt the UIScrollViewDelegate protocol. For zooming and panning to work, the delegate must implement both viewForZoomingInScrollView: and scrollViewDidEndZooming:withView:atScale:; in addition, the maximum (maximumZoomScale) and minimum ( minimumZoomScale) zoom scale must be different.

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
  return self.fullScreenView;
}


-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale
{}

The scrollViewDidEndZooming method can stay empty for now. If you already did that or it still doesnt work, please post more of your code and then it is easier to help more specifically.

查看更多
登录 后发表回答