Search code examples
iosswiftzoomingpinchzoom

Double Tap to Zoom In/Out


I have an app that displays a bunch of pictures when the user presses the button from a text list view screen. I have a specific subclass that allows the user to pinch and zoom in, but I am curious as to what code I need to enter in my particular swift file to allow the user to double tap to zoom in and out. I get three errors using this code. Two say "Value of type 'ZoomingScrollView' has no member 'scrollview' or 'imageview' " and also " 'CGRectZero' is unavaiable in Swift" My code for the subclass that allows the user to zoom in is below along with the code I am using to double tap to zoom.

import UIKit

class ZoomingScrollView: UIScrollView, UIScrollViewDelegate {

 @IBOutlet weak var viewForZooming: UIView? = nil {
didSet {
    self.delegate = self
} }

func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
return viewForZooming }

@IBAction func userDoubleTappedScrollview(recognizer:  UITapGestureRecognizer) {
if let scrollV = self.scrollview {
    if (scrollV.zoomScale > scrollV.minimumZoomScale) {
        scrollV.setZoomScale(scrollV.minimumZoomScale, animated: true)
    }
    else {
        //(I divide by 3.0 since I don't wan't to zoom to the max upon the double tap)
        let zoomRect = self.zoomRectForScale(scrollV.maximumZoomScale / 3.0, center: recognizer.locationInView(recognizer.view))
        self.scrollview?.zoomToRect(zoomRect, animated: true)
    }
} }

func zoomRectForScale(scale : CGFloat, center : CGPoint) -> CGRect {
var zoomRect = CGRectZero
if let imageV = self.imageView {
    zoomRect.size.height = imageV.frame.size.height / scale;
    zoomRect.size.width  = imageV.frame.size.width  / scale;
    let newCenter = imageV.convertPoint(center, fromView: self.scrollview)
    zoomRect.origin.x = newCenter.x - ((zoomRect.size.width / 2.0));
    zoomRect.origin.y = newCenter.y - ((zoomRect.size.height / 2.0));
}
return zoomRect; }}

Solution

  • The issue seems to be that you copied some code from a view controller that had a scrollView and imageView outlet. I'm guessing your viewForZooming: UIView is your image view that you are zooming on. You also don't have to reference self.scrollView anymore because self is the scroll view since you're subclassing scroll view :) I think the code below should fix your problem (note: it's in the latest swift syntax. what you posted was not, so you may have to switch the code back to the old style if necessary. You should try to use the latest Swift though). Good luck and let me know if you have questions.

    import UIKit
    
    class ZoomingScrollView: UIScrollView, UIScrollViewDelegate {
    
        @IBOutlet weak var viewForZooming: UIView? = nil {
            didSet {
                self.delegate = self
            } }
    
        func viewForZoomingInScrollView(scrollView: UIScrollView) -> UIView? {
            return viewForZooming }
    
        @IBAction func userDoubleTappedScrollview(recognizer:  UITapGestureRecognizer) {
            if (zoomScale > minimumZoomScale) {
                setZoomScale(minimumZoomScale, animated: true)
            }
            else {
                //(I divide by 3.0 since I don't wan't to zoom to the max upon the double tap)
                let zoomRect = zoomRectForScale(scale: maximumZoomScale / 3.0, center: recognizer.location(in: recognizer.view))
                zoom(to: zoomRect, animated: true)
            }
        }
    
        func zoomRectForScale(scale : CGFloat, center : CGPoint) -> CGRect {
            var zoomRect = CGRect.zero
            if let imageV = self.viewForZooming {
                zoomRect.size.height = imageV.frame.size.height / scale;
                zoomRect.size.width  = imageV.frame.size.width  / scale;
                let newCenter = imageV.convert(center, from: self)
                zoomRect.origin.x = newCenter.x - ((zoomRect.size.width / 2.0));
                zoomRect.origin.y = newCenter.y - ((zoomRect.size.height / 2.0));
            }
            return zoomRect;
        }
    }