我正在尝试为我的其中一个 View 实现分页交互。我以为我会使用 UISwipeGestureRecognizers
.但通过反复试验以及对文档的检查,看来
A swipe is a discrete gesture, and thus the associated action message is sent only once per gesture.
因此,虽然我可以触发页面,但我无法连接拖动过程中发生的动画。
我唯一的选择是使用 UIPanGestureRecognizer
并重新实现滑动的基本过滤/计算?
更新/减少
事后看来,我真正应该问的是如何实现“轻弹”手势。如果您不打算推出自己的子类(可能会稍微取消它),您可以使用 UIPanGestureRecognizer 作为@Lyndsey 的答案所示。在那之后(在评论中)我一直在寻找的是如何做轻弹部分,轻弹的动量有助于决定是继续轻弹的 Action 还是快速回到原始演示。
UIScrollView 具有类似的行为,很容易挖掘其实现以了解如何以一致的方式减速势头的详细信息,但遗憾的是 decelerationRate
为 UIScrollView
提供是“每次迭代”值(根据某些人的说法)。我一直在思考如何将默认值 0.998 正确应用到平移的最终速度。
最后,我使用了从有关“轻弹”计算的站点中提取的代码,并在我的手势处理程序中做了类似的事情:
...
else if (pan.state == UIGestureRecognizerStateEnded) {
CGFloat v = [pan velocityInView: self.view].x;
CGFloat a = -4000.0; // 4 pixels/millisecond, recommended on gavedev
CGFloat decelDisplacement = -(v * v) / (2 * a); // physics 101
// how far have we come plus how far will momentum carry us?
CGFloat totalDisplacement = ABS(translation) + decelDisplacement;
// if that is (or will be) half way across our view, finish the transition
if (totalDisplacement >= self.view.bounds.size.width / 2) {
// how much time would we need to carry remainder across view with current velocity and existing displacement? (capped)
CGFloat travelTime = MIN(0.4, (self.view.bounds.size.width - ABS(translation)) * 2 / ABS(v));
[UIView animateWithDuration: travelTime delay: 0.0 options: UIViewAnimationOptionCurveEaseOut animations:^{
// target/end animation positions
} completion:^(BOOL finished) {
if (finished) {
// any final state change
}
}];
}
else { // put everything back the way it was
...
}
}
最佳答案
是的,如果您想要“滑动”的特定速度、角度、变化等来触发您的动画,请使用 UIPanGestureRecognizer
。 UISwipeGestureRecognizer
确实是一个单独的离散手势;与UITapGestureRecognizer
类似,它在识别时触发单个操作消息。
与物理学一样,UIPanGestureRecognizer
的“速度”将指示平移手势的速度和方向。这是 docs for velocityInView:
method这将帮助您计算变化的平移手势的水平和垂直分量(以每秒点数为单位)。
关于ios - 如果我想跟踪移动,是否必须使用 UIPanGestureRecognizer 而不是 UISwipeGestureRecognizer?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27070736/