基于 UIPanGestureRecognizer 速度的 UIView 动画
我希望能够在屏幕上移动子视图,就像在 iPhone 内置的照片应用程序中的图像之间浏览一样,因此,如果当我放开手指时,子视图距离屏幕超过 1/2,则它必须离屏动画,但它还必须支持滑动,因此如果滑动/平移速度足够高,它必须离屏动画,即使距离屏幕可能小于 1/2。
我的想法是使用 UIPanGestureRecognizer,然后测试速度。这是可行的,但是如何根据视图的当前位置和平移速度为 UIView 的移动设置正确的动画持续时间,使其看起来平滑?如果我设置一个固定值,与我的手指滑动速度相比,动画要么开始变慢,要么变快。
I would like to be able to move a subview on and off the screen much like you browse between images in the iPhone's build in Photos app, so if the subview is more than 1/2 off screen when I let go with my finger it must animate off screen, but it must also support swipe so if the swipe/pan velocity is high enough it must animate off screen even though is might be less than 1/2 off screen.
My idea was to use UIPanGestureRecognizer and then test on the velocity. This works, but how do I set a correct animation duration for the moving of the UIView based on the view's current location and velocity of the pan so that it seems smooth? If I set a fixed value, the animation either starts to slow or to fast compared to my fingers swipe speed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
文档说
所以我想说,假设您想要移动视图 xPoints(以 pt 为单位)以使其离开屏幕,您可以像这样计算该移动的持续时间:
您可能想要使用+ (void)animateWithDuration:(NSTimeInterval)持续时间延迟:(NSTimeInterval)延迟选项:(UIViewAnimationOptions)选项动画:(void (^)(void))动画完成:(void (^)(BOOL 完成)) 完成 相反,并尝试不同的
UIViewAnimationOptions
。The docs say
So I'd say, given you want to move your view
xPoints
(measured in pt) to let it go off-screen, you could calculate the duration for that movement like so:You might want to use
+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion
instead though and try out differentUIViewAnimationOptions
.关于依赖
UIPanGestureRecognizer
中速度的观察:我不知道您的经验,但我发现系统在模拟器上生成的速度并不是很有用。 (在设备上没问题,但在模拟器上有问题。)如果您快速平移并突然停止,等待,然后才结束手势(例如,用户开始滑动,意识到这不是他们想要的,所以他们停止然后松开手指),松开手指时
UIGestureRecognizerStateEnded
状态下velocityInView:
报告的速度似乎是我停下来之前的最快速度,等待,而本例中的正确速度将为零(或接近零)。简而言之,报告的速度是平移末端之前的速度,而不是平移末端本身的速度。我最终自己手动计算了速度。 (这似乎很愚蠢,这是必要的,但如果我真的想获得平移的最终速度,我没有看到任何解决办法。)底线,当状态为
UIGestureRecognizerStateChanged
时,我保留跟踪当前和上一个translationInView
CGPoint 以及时间,然后在我处于UIGestureRecognizerStateEnded
时使用这些值来计算实际的最终值 速度。它运作得很好。这是我计算速度的代码。我碰巧没有使用速度来计算动画的速度,而是使用它来确定用户是否平移足够远或轻弹足够快,以使视图在屏幕上移动超过一半,从而触发视图之间的动画,但计算最终速度的概念似乎适用于这个问题。这是代码:
An observation on relying upon the velocity in
UIPanGestureRecognizer
: I don't know about your experience, but I found the system generated velocity on the simulator to be not terribly useful. (It's ok on the device, but problematic on simulator.)If you pan quickly across and abruptly stop, wait, and only then end the gesture (e.g. user starts a swipe, realizes that this wasn't what they wanted, so they stop and then release their finger), the velocity reported by
velocityInView:
at theUIGestureRecognizerStateEnded
state when your finger was released seems to be the fast speed before I stopped and waited, whereas the right velocity in this example would be zero (or near zero). In short, the reported velocity is that which it was right before the end of the pan, but not the speed at the end of the pan itself.I ended up calculating the velocity myself, manually. (It seems silly that this is necessary, but I didn't see any way around it if I really wanted to get the final speed of the pan.) Bottom line, when the state is
UIGestureRecognizerStateChanged
I keep track of the current and previoustranslationInView
CGPoint as well as the time, and then using those values when I was in theUIGestureRecognizerStateEnded
to calculate the actual final velocity. It works pretty well.Here is my code for calculating the velocity. I happen to not be using velocity to figure out the speed of the animation, but rather I'm using it to determine whether the user either panned far enough or flicked quickly enough for the view to move more than half way across the screen and thus triggering the animation between views, but the concept of calculating the final velocity seems applicable to this question. Here's the code:
在大多数情况下,为
UIView
动画器设置UIViewAnimationOptionBeginFromCurrentState
选项足以制作完美的连续动画。In most cases setting
UIViewAnimationOptionBeginFromCurrentState
option forUIView
animator is enough to make a flawlessly continued animation.