ピンチイン・アウトとダブルタップで画像(UIImageView)を拡大する方法です
UIScrollViewにUIImageViewを設置する形で実装します
ズーム後の位置の補正はこちらを参考にさせていただきました
【iOS開発】UIScrollViewでピンチイン/アウトによる拡大縮小: ポケットのなかにはCDRがひとつ
class MainView: UIView, UIScrollViewDelegate { var scrollView: UIScrollView! = nil var imageView: UIImageView! = nil var isDoubleTap: Bool = false override init(frame: CGRect) { super.init(frame: frame) myInit() } required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) myInit() } override func layoutSubviews() { super.layoutSubviews() scrollView.frame = self.bounds imageView.frame = scrollView.bounds } /// 初期化 func myInit() { // ScrollViewを作成 scrollView = UIScrollView() scrollView.minimumZoomScale = 1 scrollView.maximumZoomScale = 5 scrollView.scrollEnabled = true scrollView.zoomScale = 1 scrollView.contentSize = self.bounds.size scrollView.delegate = self scrollView.showsHorizontalScrollIndicator = false scrollView.showsVerticalScrollIndicator = false scrollView.backgroundColor = UIColor.blackColor() self.addSubview(scrollView) // 画像を作成 let image = UIImage(named: "photo") imageView = UIImageView(image: image) imageView.userInteractionEnabled = true // 画像がタップできるようにする imageView.contentMode = UIViewContentMode.ScaleAspectFit scrollView.addSubview(imageView) // ダブルタップの準備 let doubleTapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self , action:#selector(doubleTap(_:))) doubleTapGesture.numberOfTapsRequired = 2 imageView.addGestureRecognizer(doubleTapGesture) } // MARK: - UIScrollViewDelegate /// ズームしたいUIViewを返す func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? { return imageView } /// ズーム変更 func scrollViewDidZoom(scrollView: UIScrollView) { self.updateImageCenter() } /// ズーム完了 func scrollViewDidEndZooming(scrollView: UIScrollView, withView view: UIView?, atScale scale: CGFloat) { self.updateImageCenter() isDoubleTap = false } //MARK: - /// ダブルタップ func doubleTap(gesture: UITapGestureRecognizer) -> Void { if ( scrollView.zoomScale < scrollView.maximumZoomScale ) { isDoubleTap = true var tapPoint = gesture.locationInView(gesture.view) tapPoint.x /= scrollView.zoomScale tapPoint.y /= scrollView.zoomScale let newScale:CGFloat = scrollView.zoomScale * 2 let zoomRect:CGRect = zoomRectForScale(newScale, center: tapPoint) scrollView.zoomToRect(zoomRect, animated: true) } else { // 最初のサイズに戻す scrollView.setZoomScale(1.0, animated: true) } } /// ズーム時の矩形を求める /// - parameter scale: 拡大率 /// - parameter center: 中央の座標 /// - returns: ズーム後の表示エリア func zoomRectForScale(scale:CGFloat, center: CGPoint) -> CGRect{ var zoomRect: CGRect = CGRect() zoomRect.size.height = self.frame.size.height / scale zoomRect.size.width = self.frame.size.width / scale zoomRect.origin.x = center.x - zoomRect.size.width / 2.0 zoomRect.origin.y = center.y - zoomRect.size.height / 2.0 return zoomRect } /// ズーム後の画像の位置を調整する func updateImageCenter() { // ダブルタップした場合はこの処理を行わない if isDoubleTap { return } let image = imageView.image // UIViewContentMode.ScaleAspectFit時のUIImageViewの画像サイズを求める let frame = AVMakeRectWithAspectRatioInsideRect(image!.size, imageView.bounds) var imageSize = CGSizeMake(frame.size.width, frame.size.height) imageSize.width *= scrollView.zoomScale imageSize.height *= scrollView.zoomScale var point: CGPoint = CGPointZero point.x = imageSize.width / 2 if imageSize.width < scrollView.bounds.width { point.x += (scrollView.bounds.width - imageSize.width) / 2 } point.y = imageSize.height / 2 if imageSize.height < scrollView.bounds.height { point.y += (scrollView.bounds.height - imageSize.height) / 2 } imageView.center = point } }
この実装では、ピンチイン・ピンチアウトでの拡大縮小は問題ありませんが、ダブルタップでの拡大の動作がイマイチです
今回の実装ではこんな動き
理想はこれ
今回の実装では、ダブルタップした位置が画面の中央に移動するので、同じ場所を再度拡大したい時は指を動かさないといけません。できればトントン・トントンと連続でタップすれば同じ場所が拡大してほしいところ。
というわけで、別の方法を考えます
追記)ダブルタップ位置の問題を解決したバージョンの記事を書きました

【Swift】ピンチイン・アウト・ダブルタップで画像を拡大する2(UIScrollView未使用バージョン)
前回UIScrollViewを使った画像拡大の実装方法を書きましたが、今回は別の方法で実装してみます
今回の実装では、前回の不満点だったダブルタップでのズーム位置のズレが解消されています
前回の不満点
今回...