LoginSignup
4
2

More than 5 years have passed since last update.

UICollectionViewCellにinstagramのようなズーム機能をつける

Posted at

コード

参考にした記事
https://medium.com/@jeremysh/instagram-pinch-to-zoom-pan-gesture-tutorial-772681660dfe

var isZooming = false
var originalImageCenter:CGPoint?
let pinch = UIPinchGestureRecognizer(target: self, action: #selector(self.pinch(sender:)))
pinch.delegate = self
self.photoScrollView.addGestureRecognizer(pinch)

let pan = UIPanGestureRecognizer(target: self, action: #selector(self.pan(sender:)))
pan.delegate = self
self.photoScrollView.addGestureRecognizer(pan)
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }
@objc func pinch(sender: UIPinchGestureRecognizer) {

        delegate?.didPinch()

        if sender.state == .began {
            let currentScale = self.photoScrollView.frame.size.width / self.photoScrollView.bounds.size.width
            let newScale = currentScale * sender.scale

            if newScale > 1 {
                self.isZooming = true
            }
        } else if sender.state == .changed {

            guard let view = sender.view else { return }

            let pinchCenter = CGPoint(x: sender.location(in: view).x - view.bounds.midX,
                                      y: sender.location(in: view).y - view.bounds.midY)
            let transform = view.transform.translatedBy(x: pinchCenter.x, y: pinchCenter.y)
                .scaledBy(x: sender.scale, y: sender.scale)
                .translatedBy(x: -pinchCenter.x, y: -pinchCenter.y)

            let currentScale = self.photoScrollView.frame.size.width / self.photoScrollView.bounds.size.width
            var newScale = currentScale * sender.scale

            if newScale < 1 {
                newScale = 1
                let transform = CGAffineTransform(scaleX: newScale, y: newScale)
                self.photoScrollView.transform = transform
                sender.scale = 1
            } else {
                view.transform = transform
                sender.scale = 1
            }

        } else if sender.state == .ended || sender.state == .failed || sender.state == .cancelled {

            delegate?.didFinishPinch()

            guard let center = self.originalImageCenter else {return}

            UIView.animate(withDuration: 0.3, animations: {
                self.photoScrollView.transform = CGAffineTransform.identity
                self.photoScrollView.center = center
            }, completion: { _ in
                self.isZooming = false
            })
        }
    }

    @objc func pan(sender: UIPanGestureRecognizer) {

        if self.isZooming && sender.state == .began {
            self.originalImageCenter = sender.view?.center
        } else if self.isZooming && sender.state == .changed {
            let translation = sender.translation(in: self)
            if let view = sender.view {
                view.center = CGPoint(x:view.center.x + translation.x,
                                      y:view.center.y + translation.y)
            }
            sender.setTranslation(CGPoint.zero, in: self.photoScrollView.superview)
        }
    }

あとはdelegateをcollectionViewControllerまで引っ張っていった。

    func didPinch() {
        collectionView.isScrollEnabled = false
    }

    func didFinishPinch() {
        collectionView.isScrollEnabled = true
    }
4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2