22

I'm developing an application to display a gallery of UIImages by using a UIScrollView, my question is, how to tap to zoom and double tap to zoom out, how does it work when handling with UIScrollView.

Larme
  • 24,190
  • 6
  • 51
  • 81
Bruno
  • 1,032
  • 1
  • 16
  • 40

2 Answers2

39

You need to implement UITapGestureRecognizer - docs here - in your viewController

- (void)viewDidLoad
{
    [super viewDidLoad];       

    // what object is going to handle the gesture when it gets recognised ?
    // the argument for tap is the gesture that caused this message to be sent
    UITapGestureRecognizer *tapOnce = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapOnce:)];
    UITapGestureRecognizer *tapTwice = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTwice:)];

    // set number of taps required
    tapOnce.numberOfTapsRequired = 1;
    tapTwice.numberOfTapsRequired = 2;

    // stops tapOnce from overriding tapTwice
    [tapOnce requireGestureRecognizerToFail:tapTwice];

    // now add the gesture recogniser to a view 
    // this will be the view that recognises the gesture  
    [self.view addGestureRecognizer:tapOnce];
    [self.view addGestureRecognizer:tapTwice];

}

Basically this code is saying that when a UITapGesture is registered in self.view the method tapOnce or tapTwice will be called in self depending on if its a single or double tap. You therefore need to add these tap methods to your UIViewController:

- (void)tapOnce:(UIGestureRecognizer *)gesture
{
    //on a single  tap, call zoomToRect in UIScrollView
    [self.myScrollView zoomToRect:rectToZoomInTo animated:NO];
}
- (void)tapTwice:(UIGestureRecognizer *)gesture
{
    //on a double tap, call zoomToRect in UIScrollView
    [self.myScrollView zoomToRect:rectToZoomOutTo animated:NO];
}

Hope that helps

GWed
  • 15,167
  • 5
  • 62
  • 99
3

Swift 4.0 version that zooms twice on double tap.

@IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var imageView: UIImageView!

Somewhere (usually in viewDidLoad):

let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(onDoubleTap(gestureRecognizer:)))
tapRecognizer.numberOfTapsRequired = 2
scrollView.addGestureRecognizer(tapRecognizer)

Handler:

@objc func onDoubleTap(gestureRecognizer: UITapGestureRecognizer) {
    let scale = min(scrollView.zoomScale * 2, scrollView.maximumZoomScale)
    
    if scale != scrollView.zoomScale {
        let point = gestureRecognizer.location(in: imageView)

        let scrollSize = scrollView.frame.size
        let size = CGSize(width: scrollSize.width / scale,
                          height: scrollSize.height / scale)
        let origin = CGPoint(x: point.x - size.width / 2,
                             y: point.y - size.height / 2)
        scrollView.zoom(to:CGRect(origin: origin, size: size), animated: true)
        print(CGRect(origin: origin, size: size))
    }
}
Krunal Nagvadia
  • 1,083
  • 2
  • 12
  • 33
Avt
  • 16,927
  • 4
  • 52
  • 72
  • This still works the same way in Swift 5/Xcode 12.4. To zoom out with another double tap (and an animation) you can simply add the following to the `else` part: `scrollView.setZoomScale(scrollView.minimumZoomScale, animated: true)` – Neph Apr 15 '21 at 13:21