iOS Swift tutorial : ImageView zooming and horizontal paging
By: Amsaraj Mariyappan
Tags: Scrollview, Zoom, Paging, Swif, iOS

Pinch to zoom image

When we are make an application, which has a photo viewer feature for any Details view pages, the photo viewer usually needs to have zoomable and scrollable features, that allows your user viewing photo more details. This control will help you to display images, with zoomable and scrollable features easily. We are going to achieve this feature help of UIScrollView.

And click here download full project and then open it in Xcode.

We can create demo application, after creation sample app in ViewController we can add one UIScrollView subview for paging in our current view.

let viewHeight: CGFloat = self.view.bounds.size.height

let viewWidth: CGFloat = self.view.bounds.size.width let scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: viewWidth, height: viewHeight))

self.view.addSubview(scrollView)

And this scrollview we are going to use like a horizontal page view. so need to add page option for scrollView.

scrollView.isPagingEnabled = true

After add this we can start to add horizontal page ImageView for view and Zoom image. Before start code we need to images so i am creating one image folder and adding the images in that folder. After adding images we can create image array.

let animals = [“tiger”,”horse”,”lion”,”rabbit”,”elephant”]

Now we have image array list. so we can able to add images in scrollView.

var xPostion: CGFloat = 0 for animal in animals { let view = UIView(frame: CGRect(x: xPostion, y: 0,

width: viewWidth, height: viewHeight)) let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height)) imageView.image = UIImage(named:animal)) view.addSubview(imageView) scrollView.addSubview(view)

} scrollView.contentSize = CGSize(width: xPostion, height: viewHeight)

now we have horizontal page with images. but we don’t have zoom in and out option. so we can move for that.

Create new open class for image zooming and scrolling. I have created ImageViewZoom.swift file and this class has extended from UIScrollView, also created delegate protocol for callBacks.

open class ImageViewZoom: UIScrollView {

} @objc public protocol ImageViewZoomDelegate: UIScrollViewDelegate {

}

Then we can initialise scrollView

required public init?(coder aDecoder: NSCoder) {

super.init(coder: aDecoder)

initialize()

} private func initialize() {

showsVerticalScrollIndicator = false

showsHorizontalScrollIndicator = false

bouncesZoom = true

decelerationRate = UIScrollView.DecelerationRate.fast

delegate = self

}

after done initialize, we can add UIImageView subView for scrollView and added UITapGestureRecognizer for image double tap action handle.

@objc public private(set) var zoomView: UIImageView? = nil @objc open func display(image: UIImage) {

if let zoomView = zoomView {

zoomView.removeFromSuperview()

}

zoomView = UIImageView(image: image)

zoomView!.isUserInteractionEnabled = true

addSubview(zoomView!)

let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ImageViewZoom.doubleTapGestureRecognizer(_:)))

tapGesture.numberOfTapsRequired = 2 zoomView!.addGestureRecognizer(tapGesture)

}

This imageView need a contentMode as well so we can create enum for ScaleMode like below

@objc public enum ScaleMode: Int {

case aspectFill

case aspectFit

case widthFill

case heightFill

}

if we tap imageView two time need to resize image and after resize image again if we click two time need to back same size.

@objc func doubleTapGestureRecognizer(_ gestureRecognizer: UIGestureRecognizer) { // zoom out if it bigger than middle scale point. Else, zoom in if zoomScale >= maximumZoomScale / 2.0 {

setZoomScale(minimumZoomScale, animated: true)

} else {

let center = gestureRecognizer.location(in: gestureRecognizer.view)

let zoomRect = zoomRectForScale(ImageViewZoom.kZoomInFactorFromMinWhenDoubleTap * minimumZoomScale, center: center)

zoom(to: zoomRect, animated: true) }

} private func zoomRectForScale(_ scale: CGFloat, center: CGPoint) -> CGRect { var zoomRect = CGRect.zero

zoomRect.size.height = frame.size.height / scale

zoomRect.size.width = frame.size.width / scale // choose an origin so as to get the right center. zoomRect.origin.x = center.x — (zoomRect.size.width / 2.0)

zoomRect.origin.y = center.y — (zoomRect.size.height / 2.0)

return zoomRect

}

and need to handle scrollView delegate and TapGestures also. after done all this we can use this class for instead of UIImageView in ViewContoller.

for animal in animals { let view = UIView(frame: CGRect(x: xPostion, y: 0, width: viewWidth, height: viewHeight)) xPostion += viewWidth let imageView = ImageViewZoom(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: view.frame.size.height)) imageView.setup() imageView.imageScrollViewDelegate = self imageView.imageContentMode = .aspectFit imageView.initialOffset = .center imageView.display(image: UIImage(named: animal)!) view.addSubview(imageView) scrollView.addSubview(view) }

After run this application I can able to do Zoom in and out with horizontal paging like a photo viewer. You can download the completed sample code of this tutorial from here.