Created
September 8, 2016 20:03
-
-
Save vickeryj/ec24f320d8469b87258f55b697aa42f1 to your computer and use it in GitHub Desktop.
Zoom into and page through an array of images
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
class FullscreenPhotoViewController: UIViewController, UIScrollViewDelegate { | |
// MARK: - IBOutlets | |
@IBOutlet weak var scrollView: UIScrollView! | |
// MARK: - IBActions | |
@IBAction func closeButtonTapped(sender: AnyObject) { | |
dismissViewControllerAnimated(true, completion: nil) | |
} | |
// MARK: - Private Properties | |
private let imageViewTag = 1 | |
// MARK: Public Properties | |
var images: [UIImage]? | |
var currentImageIndex: Int? | |
// MARK: UIViewController | |
override func viewDidLayoutSubviews() { | |
setupNestedImageScrollViews() | |
} | |
override func viewDidAppear(animated: Bool) { | |
Analytics.service.pageView(.FullScreenPhoto) | |
} | |
// MARK: UIScrollViewDelegate | |
func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? { | |
return scrollView.viewWithTag(imageViewTag) | |
} | |
func scrollViewDidZoom(scrollView: UIScrollView) { | |
centerImageIfSmallerThanView(scrollView) | |
} | |
func scrollViewDidScroll(scrollView: UIScrollView) { | |
if scrollView == self.scrollView { | |
currentImageIndex = Int(round(scrollView.contentOffset.x / scrollView.bounds.width)) | |
} | |
} | |
// MARK: Private Functions | |
private func setupNestedImageScrollViews() { | |
for view in scrollView.subviews { | |
view.removeFromSuperview() | |
} | |
let previousImageIndex = currentImageIndex | |
scrollView.bounds = view.bounds | |
scrollView.contentOffset = CGPointZero | |
if let images = images { | |
var imageScrollViewFrame = scrollView.bounds | |
for image in images { | |
let imageView = UIImageView(image: image) | |
imageView.tag = imageViewTag | |
let imageScrollView = UIScrollView(frame: imageScrollViewFrame) | |
imageScrollView.addSubview(imageView) | |
imageScrollView.contentSize = imageView.bounds.size | |
imageScrollView.delegate = self | |
scrollView.addSubview(imageScrollView) | |
zoomImageToFit(imageScrollView) | |
centerImageIfSmallerThanView(imageScrollView) | |
imageScrollViewFrame.origin.x += imageScrollViewFrame.size.width | |
} | |
scrollView.contentSize = CGSizeMake(CGFloat(images.count) * scrollView.bounds.width, scrollView.bounds.height) | |
currentImageIndex = previousImageIndex | |
setOffsetToCurrentImageIndex() | |
} | |
} | |
private func centerImageIfSmallerThanView(imageScrollView: UIScrollView) { | |
guard let imageView = imageScrollView.viewWithTag(imageViewTag) as? UIImageView, | |
image = imageView.image else { return } | |
var imageViewFrame = imageView.frame | |
let yOffset = max(0, (view.bounds.size.height - (image.size.height * imageScrollView.zoomScale)) / 2) | |
imageViewFrame.origin.y = yOffset | |
let xOffset = max(0, (view.bounds.size.width - (image.size.width * imageScrollView.zoomScale)) / 2) | |
imageViewFrame.origin.x = xOffset | |
imageView.frame = imageViewFrame | |
} | |
private func zoomImageToFit(imageScrollView: UIScrollView) { | |
guard let imageView = imageScrollView.viewWithTag(imageViewTag) as? UIImageView, | |
image = imageView.image else { return } | |
let scrollViewFrame = imageScrollView.frame | |
let scaleWidth = scrollViewFrame.size.width / image.size.width | |
let scaleHeight = scrollViewFrame.size.height / image.size.height | |
let minScale = min(scaleHeight, scaleWidth) | |
imageScrollView.minimumZoomScale = minScale | |
imageScrollView.maximumZoomScale = 1 | |
imageScrollView.zoomScale = minScale | |
} | |
private func setOffsetToCurrentImageIndex() { | |
guard let images = images, index = currentImageIndex else { return } | |
if images.count > index { | |
scrollView.contentOffset = CGPointMake(scrollView.bounds.width * CGFloat(index), 0) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment