UIImageView and UIScrollView zooming

I did a custom image viewer not a long ago without the pinch recognizers. Just UIImageView on top of UIScrollView. There you pass a string with a link to the image and it also has a progress bar. Once that image is finished loading the image is shown. Here's the code:

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

- (CGRect)centeredFrameForScrollView:(UIScrollView *)scroll andUIView:(UIView *)rView {
  CGSize boundsSize = scroll.bounds.size;
  CGRect frameToCenter = rView.frame;
  // center horizontally
  if (frameToCenter.size.width < boundsSize.width) {
    frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;
  }
  else {
    frameToCenter.origin.x = 0;
  }
  // center vertically
  if (frameToCenter.size.height < boundsSize.height) {
    frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;
  }
  else {
    frameToCenter.origin.y = 0;
  }
  return frameToCenter;
}

-(void)scrollViewDidZoom:(UIScrollView *)scrollView
{
  self.theImageView.frame = [self centeredFrameForScrollView:self.theScrollView andUIView:self.theImageView];                               
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
  [self.resourceData setLength:0];
  self.filesize = [NSNumber numberWithLongLong:[response expectedContentLength]];
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
  [self.resourceData appendData:data];
  NSNumber *resourceLength = [NSNumber numberWithUnsignedInteger:[self.resourceData length]];
  self.progressBar.progress = [resourceLength floatValue] / [self.filesize floatValue];
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
  self.theImage = [[UIImage alloc]initWithData:resourceData];
  self.theImageView.frame = CGRectMake(0, 0, self.theImage.size.width, self.theImage.size.height);
  self.theImageView.image = self.theImage;
  self.theScrollView.minimumZoomScale = self.theScrollView.frame.size.width / self.theImageView.frame.size.width;
  self.theScrollView.maximumZoomScale = 2.0;
  [self.theScrollView setZoomScale:self.theScrollView.minimumZoomScale];
  self.theScrollView.contentSize = self.theImageView.frame.size;
  self.theLabel.hidden = YES;
  self.progressBar.hidden = YES;
}

-(void)setImageInImageView
{
  NSURLRequest *req = [[NSURLRequest alloc]initWithURL:[NSURL URLWithString:self.imageLink]];
  NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:req delegate:self];
  if (conn)
  {
    self.resourceData = [NSMutableData data];
  }
  else
  {
    NSLog(@"Connection failed: IMageViewerViewController");
  }
}

-(void)loadView
{
  self.filesize = [[NSNumber alloc]init];
  self.progressBar = [[UIProgressView alloc]initWithProgressViewStyle:UIProgressViewStyleBar];
  self.progressBar.frame = CGRectMake(20, 240, 280, 40);
  [self.progressBar setProgress:0.0];
  self.theImageView = [[[UIImageView alloc]initWithFrame:[[UIScreen mainScreen]applicationFrame]]autorelease];
  self.theScrollView = [[[UIScrollView alloc]initWithFrame:[[UIScreen mainScreen]applicationFrame]]autorelease];
  self.theScrollView.delegate = self;
  [self.theScrollView addSubview:self.theImageView];
  self.view = self.theScrollView;
  self.theLabel = [[UILabel alloc]initWithFrame:CGRectMake(0, 200, 320, 40)];
  self.theLabel.font = [UIFont boldSystemFontOfSize:15.0f];
  self.theLabel.text = @"Please wait, file is being downloaded";
  self.theLabel.textAlignment = UITextAlignmentCenter;
  self.theLabel.hidden = NO;
  [self.view addSubview:self.progressBar];
  [self.view bringSubviewToFront:self.progressBar];
  [self.view addSubview:self.theLabel];
  [self.view bringSubviewToFront:self.    theLabel];
  [self performSelectorOnMainThread:@selector(setImageInImageView) withObject:nil waitUntilDone:NO];
}

And the header file:

@interface ImageViewerViewController : UIViewController<UIScrollViewDelegate, NSURLConnectionDelegate, NSURLConnectionDataDelegate>

@property (nonatomic, retain) IBOutlet UIImageView *theImageView;
@property (nonatomic, retain) IBOutlet UIScrollView *theScrollView;
@property (nonatomic, retain) NSString *imageLink;
@property (nonatomic, retain) UIImage *theImage;
@property (nonatomic, retain) UILabel *theLabel;
@property (nonatomic, retain) UIProgressView *progressBar;
@property (nonatomic, retain) NSMutableData *resourceData;
@property (nonatomic, retain) NSNumber *filesize;
@end

Hope it helps


All you need to do is add your UIImageView (or any view you want to zoom) inside your UIScrollView.

Set your maximumZoomScale on your UIScrollView to any value higher than 1.0f.

Set yourself as the delegate of your UIScrollView and return the UIImageView in the viewForZooming delegate method.

That's it. No pinch gesture needed, no nothing. UIScrollView handles pinch zooming for you.


Objective C

Pinch-zoom Image in Scrollview Steps (Objective C)

1. Scroll View Constraints

enter image description here

2. Add ImageView In ScrollView and set Constraints

enter image description here

3. Take IBOutlets

IBOutlet UIScrollView * bgScrollView;
IBOutlet UIImageView * imageViewOutlet;

4. viewDidLoad Method

- (void)viewDidLoad
 {
    [super viewDidLoad];

    float minScale=bgScrollView.frame.size.width / imageViewOutlet.frame.size.width;
    bgScrollView.minimumZoomScale = minScale;
    bgScrollView.maximumZoomScale = 3.0;
    bgScrollView.contentSize = imageViewOutlet.frame.size;
    bgScrollView.delegate = self;
}

5. Scroll View Delegate Method

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
    return imageViewOutlet;
}

Swift

Pinch-zoom Image in Scrollview Steps (Swift)

1. Scroll View Constraints

enter image description here

2. Add ImageView In ScrollView and set Constraints

enter image description here

3. Take IBOutlets

@IBOutlet weak var bgScrollView : UIScrollView!
@IBOutlet weak var imageView : UIImageView!

4. viewDidLoad Method

 override func viewDidLoad() {
    super.viewDidLoad()

    let minScale = bgScrollView.frame.size.width / imageView.frame.size.width;
    bgScrollView.minimumZoomScale = minScale
    bgScrollView.maximumZoomScale = 3.0
    bgScrollView.contentSize = imageView.frame.size
    bgScrollView.delegate = self
}

5. Scroll View Delegate Method

func viewForZooming(in scrollView: UIScrollView) -> UIView? {
    return imageView
}