pinchとdouble tapでzoomするUIImageViewを作る
ピンチイン/アウトでズームアウト/インをして、さらにダブルタップで何段階かに拡大して元の縮尺に戻るUIImageView
を作成したので簡単にメモ。
ピンチでズームするUIImageView
UIScrollView
を使ってUIImageView
をピンチでズームするコードは検索すればいくらでも出てくるが一応手順を記録しておく。
UIScrollViewの中にUIImageViewを置く
まずはズームしたいUIImageView
をUIScrollView
の中に置く必要がある。
これはStoryboard
で行う場合にはUIImageView
を選択してからEditor
メニューのEmbed in
でScroll View
を選択する。
コードの場合はUIScrollView
にaddSubview(_ view:)
で行う。
scrollView.addSubview(imageView)
UIScrollViewのdelegateを設定
Storyboard
でも繋げるしUIViewController
のコードで書いても良い
scrollView.delegate = self
UIScrollViewのmaximumZoomScaleを設定
デフォルトではmaximumZoomScale
が1になっているのでそのままだとズームしない。
今回は4倍までズームするようにした。
self.scrollView.maximumZoomScale = 4.0
UIViewControllerをUIScrollViewDelegateプロトコルに対応する
UIScrollViewDelegate
に必須の関数はないがズームにはviewForZooming(in:)
が必要。返す値はUIScrollView
に含まれるUIImageView
。
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return imageView
}
以上でUIImageVIew
をピンチでズームできるようになる。
今回はダブルタップで2倍、4倍にズームできるようにする必要があったので更に後述するUITapGestureRecognizer
を使用している。
ダブルタップでズームするようにする
これはを行うにはUITapGestureRecognizer
を使用してイベントを取得し、マニュアルで画像サイズを変更する。
手順としては以下の通り。
UIScrollViewにUITapGestureRecognizerを設定
UIScrollView
がダブルタップに反応するようにUITapGestureRecognizer
をセットする。
UITapGestureRecognizer
はダブルタップに反応するようにnumberOfTapRequired
を2に設定している。
let recognizer = UITapGestureRecognizer(target: self,
action: #selector(onDoubleTap(_:)))
recognizer.numberOfTapsRequired = 2
scrollView.addGestureRecognizer(recognizer)
ダブルタップ時のアクションに画像をズームするコードを書く
具体的にはUIScrollView
の大きさとscale
から画像の表示される範囲を計算して、UIScrollView
をその範囲にズームしている。
また、既に最大の4倍までズームされている場合には1倍の状態に戻している。
@objc func onDoubleTap(_ sender: UITapGestureRecognizer) {
let scale = min(scrollView.zoomScale * 2, scrollView.maximumZoomScale)
if scale != scrollView.zoomScale {
let tapPoint = sender.location(in: imageView)
let size = CGSize(width: scrollView.frame.size.width / scale,
height: scrollView.frame.size.height / scale)
let origin = CGPoint(x: tapPoint.x - size.width / 2,
y: tapPoint.y - size.height / 2)
scrollView.zoom(to: CGRect(origin: origin, size: size), animated: true)
}
else {
scrollView.zoom(to: scrollView.frame, animated: true)
}
}
コード
ピンチとダブルタップでズームするUIImageView
を使ったViewController
のコードはGitHubに置いてある。
Discussion