How to setup Pinch to Zoom for an image in RubyMotion

Neeraj Singh

By Neeraj Singh

on August 27, 2013

In this post we will see how to build "pinch to zoom" functionality to zoom in an image in RubyMotion.

First let's add a UIViewController that is initialized with an image.

1class ImageViewController < UIViewController
2  def initWithImage(image)
3    @image = image
4  end

UIScrollView and UIImageView

Now, we will add a UIScrollView with frame size set to full screen size and some other properties as listed below.

1scrollView = UIScrollView.alloc.initWithFrame(UIScreen.mainScreen.bounds)
2scrollView.scrollEnabled = false
3scrollView.clipsToBounds = true
4scrollView.contentSize = @image.size
5scrollView.minimumZoomScale = 1.0
6scrollView.maximumZoomScale = 4.0
7scrollView.zoomScale = 0.3

Create a new UIImageView and add it to the scrollView created above.

1imageView = UIImageView.alloc.initWithImage(@image)
2imageView.contentMode = UIViewContentModeScaleAspectFit
3imageView.userInteractionEnabled = true
4imageView.frame = scrollView.bounds

We are setting the image view's content mode to UIViewContentModeScaleAspectFit. Content mode can be set to either UIViewContentModeScaleToFill, UIViewContentModeAspectFill or UIViewContentModeScaleAspectFit depending on what suits your app. By default, contentMode property for most views is set to UIViewContentModeScaleToFill, which causes the view’s contents to be scaled to fit the new frame size. This Apple doc explains this behavior.

We need to add the above imageView as a subview to our scrollView.


This is how our controller looks with all the above additions.

1class ImageViewController < UIViewController
3  def initWithImage(image)
4    @image = image
5    scrollView = UIScrollView.alloc.initWithFrame(UIScreen.mainScreen.bounds)
6    scrollView.scrollEnabled = false
7    scrollView.clipsToBounds = true
8    scrollView.contentSize = @image.size
9    scrollView.minimumZoomScale = 1.0
10    scrollView.maximumZoomScale = 4.0
11    scrollView.zoomScale = 0.3
12    scrollView.delegate = self
14    imageView = UIImageView.alloc.initWithImage(@image)
15    imageView.contentMode = UIViewContentModeScaleToFill
16    imageView.userInteractionEnabled = true
17    imageView.frame = scrollView.bounds
18    init
19  end

ScrollView delegate

We must set a delegate for our scroll view to support zooming. The delegate object must conform to the UIScrollViewDelegate protocol. This is the reason we are setting scrollView.delegate = self above. The delegate class must implement viewForZoomingInScrollView and scrollViewDidZoom methods.

1def viewForZoomingInScrollView(scrollView)
2  scrollView.subviews.first
5def scrollViewDidZoom(scrollView)
6  if scrollView.zoomScale != 1.0
7    scrollView.scrollEnabled = true
8  else
9    scrollView.scrollEnabled = false
10  end

These two methods added above allow the scrollView to support pinch to zoom.

Supporting orientation changes

There is one more thing to do if we want to support orientations changes. We need to add the following methods:

1def shouldAutorotateToInterfaceOrientation(*)
2  true
5def viewDidLayoutSubviews
6  @scrollView.frame = self.view.bounds

We have to set the scrollView's frame to view bounds in viewDidLayoutSubviews so that the scrollView frame is resized when the device orientation changes.

That's it. With all those changes now our app supports orientation change and now we are able to pinch and zoom images.

Stay up to date with our blogs. Sign up for our newsletter.

We write about Ruby on Rails, ReactJS, React Native, remote work,open source, engineering & design.