如何取消 UIScrollView 缩放弹跳?
我正在使用缩放 UIScrollView 在我的 iPad 应用程序中显示图像。缩放效果非常好,捏一下就可以根据需要缩小或放大图像。我还启用了 bouncesZoom
,这样,如果用户以一种或另一种方式将其拉伸得太远,它就会弹回到最小或最大缩放。
现在,我想识别何时捏合结束且图像比最小缩放尺寸小 10%,在这种情况下,防止发生反弹并触发不同的动画,缩小图像以“关闭”它。这样,可以有一种“捏合关闭”手势。我想出的最简单的做法是:
- (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;
}
}
这非常有效,只是此时它已经在弹跳,因此 minimumZoomScale
的设置不会执行任何操作。因此,反弹和收缩是同时发生的,正如你想象的那样,这看起来很奇怪。
所以我的问题是:如何防止仅在这种特定情况下发生反弹?没有 UIScrollViewDelegate 方法允许我的代码在手势完成和 UIScrollView 决定反弹之间执行某些操作。我尝试了很多其他技术,但没有成功,包括:
- 当超过 90% 缩放阈值时,从
–viewForZoomingInScrollView:
返回nil
。不起作用,因为此方法是在手势开始时调用,而不是针对缩放的每个点调用。 - 当缩放系数小于 90% 时,将
-scrollViewDidZoom:
中的bouncesZoom
设置为 false,当缩放系数大于或等于 90% 时,将其设置为 true。当比例低于 90% 时,会使图像严重抖动,因为当bouncesZoom
为 false 时,它不允许该尺寸。 - 添加
-touchesEnded:withEvent
方法。它永远不会被调用。 - 添加我自己的 UIPinchGestureRecognizer 与 UIScrollView 自己的捏捏识别器同时执行。不起作用,因为它的处理程序(和委托方法)是在 UIScrollView 的捏合手势之后调用的,这使得在我的手势告诉它不要弹跳之前决定弹跳。我尝试删除所有核心手势,添加我的,然后重新添加核心手势。但在 UIScrollView 决定它弹跳后,我的手势仍然被调用。
所以我有点不知所措。还有其他人尝试过做这样的事情吗?
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 thebouncesZoom
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您只需将此属性设置为“否”即可。
(例如,在 ViewDidLoad 中)
scrollView.bouncesZoom = NO;
You have to simply set this property to NO.
(ex. in ViewDidLoad)
scrollView.bouncesZoom = NO;
我想写下这个问题帮助我走上了寻找解决方案的道路。幸运的是,这很容易!因此,第一步,在设置
minimumZoomScale
的代码中,我还将cachedMinZoomScale
ivar 设置为相同的值。这样,当比例小于最小值的 90% 时,让反弹不发生实际上是非常简单的:基本上,当滚动视图缩放时,将
-self.minimumZoomScale
保持在如果当前缩放比例小于实际最小值的 90%,则将其设置为任何其他缩放比例的实际最小值。然后,当缩放完成时,如果我们低于 90% 的阈值,它不会恢复到任何内容,因为它已经是最小尺寸,然后只需调用新的动画来缩小以关闭。简单的。唷!
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 acachedMinZoomScale
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: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!
试试这个,
[imageScrollview setBounces:NO];
Try this,
[imageScrollview setBounces:NO];