Objective-c – How to cancel a UIScrollView zoom bounce

bouncecocoa-touchobjective cuiscrollviewzooming

I'm using a zooming UIScrollView to show images in my iPad app. The zooming works great, with a pinch making an image smaller or bigger as appropriate. I also have bouncesZoom enabled so that it bounces back to the minimum or maximum zoom if the user stretches it too far one way or the other.

Now I'd like to recognize when a pinch has ended with the image 10% smaller than the minimum zoom size and, in such a case, prevent the bounce from happening and trigger a different animation that shrinks the image to "close" it. This way, there can be a sort of "pinch to close" gesture. What I've come up with to do this, at its simplest, is this:

- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
    if (self.zoomBouncing && zoomedToScale / self.minimumZoomScale < 0.90) {
        // We've let go and were under 90% of the minimum size.
        self.minimumZoomScale = zoomedToScale;
        [self shrinkImageToNothing];
    } else {
        // How far have we gone?
        zoomedToScale = self.zoomScale;
    }
}

This works great, except that at this point it's already bouncing, so the setting of minimumZoomScale does nothing. Therefore, the bounce and shrink occur at the same time, which as you might imagine looks pretty weird.

So my question is: How can I prevent the bounce from happening only in this specific situation? There is no UIScrollViewDelegate method that allows my code to do something between when the gesture finishes and when the UIScrollView decides to bounce back. I've tried a bunch of other techniques with no luck, including:

  • Returning nil from –viewForZoomingInScrollView: when my 90% zoom threshold has been passed. Doesn't work because this method is called when the gesture begins, not for every point of the zoom.
  • Setting bouncesZoom in -scrollViewDidZoom: to false when the zoom factor is less than 90% and to true when it's greater than or equal to 90%. Makes the image shake badly when the scale gets under 90% because it disallows that size when the bouncesZoom is false.
  • Adding a -touchesEnded:withEvent method. It never gets called.
  • Adding my own UIPinchGestureRecognizer to execute concurrently with the UIScrollView's own pinch recognizer. Doesn't work because its handlers (and delegate methods) are called after UIScrollView's pinch gesture, which makes the decision to bounce before my gesture can tell it not too. I tried removing all the core gestures, adding mine, and adding the core gestures back. But my gesture was still called after UIScrollView had decided it was bouncing.

So I'm at a bit of a loss. Anyone else tried to do something like this?

Best Answer

You have to simply set this property to NO. (ex. in ViewDidLoad)

scrollView.bouncesZoom = NO;

Related Topic