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