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:
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.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.-touchesEnded:withEvent
method. It never gets called.So I'm at a bit of a loss. Anyone else tried to do something like this?
You have to simply set this property to NO. (ex. in ViewDidLoad)
scrollView.bouncesZoom = NO;
I guess writing out this question helped me to get on the road to finding the solution. And fortunately, it's quite easy! So, first step, in the code I have that sets minimumZoomScale
, I also set a cachedMinZoomScale
ivar to the same value. With that, getting the bounce not to happen when the scale is less than 90% of the minimum is actually quite straight-forward:
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
if (self.zoomScale / cachedMinZoomScale < 0.90) {
self.minimumZoomScale = self.zoomScale;
} else {
self.minimumZoomScale = cachedMinZoomScale;
}
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {
if (self.zoomScale / cachedMinZoomScale < 0.90) {
[self shrinkImageToNothing];
}
}
Basically, when the scroll view zooms, keep the -self.minimumZoomScale
at the current zoom scale if it's less than 90% of the actual minimum, but set it to that actual minimum at any other zoom scale. Then, when the zoom finishes, if we're under that 90% threshold, it won't snap back to anything because it will already be the minimum size, and then just call the new animation to shrink to close.
Simple. Phew!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With