开发者

How can I cancel a UIScrollView zoom bounce?

开发者 https://www.devze.com 2023-02-15 09:33 出处:网络
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 boun

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, incl开发者_StackOverflow社区uding:

  • 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?


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!


Try this, [imageScrollview setBounces:NO];

0

精彩评论

暂无评论...
验证码 换一张
取 消