如果我想跟踪运动,是不是必须使用 UIPanGestureRecognizer 而不是 UISwipeGestureRecognizer?

Posted

技术标签:

【中文标题】如果我想跟踪运动,是不是必须使用 UIPanGestureRecognizer 而不是 UISwipeGestureRecognizer?【英文标题】:Do I have to use a UIPanGestureRecognizer instead of a UISwipeGestureRecognizer if I want to track the movement?如果我想跟踪运动,是否必须使用 UIPanGestureRecognizer 而不是 UISwipeGestureRecognizer? 【发布时间】:2014-11-21 21:32:58 【问题描述】:

我正在尝试为我的一个视图实现分页交互。我以为我会使用UISwipeGestureRecognizers。但是通过反复试验以及对文档的检查,似乎

滑动是一个离散的手势,因此关联的动作消息 每个手势仅发送一次。

所以虽然我可以触发页面,但我无法连接在拖动过程中发生的动画。

我唯一的选择是使用UIPanGestureRecognizer 并重新实现滑动的基本过滤/计算吗?

更新/Redux

事后看来,我真正应该问的是如何实现“轻弹”手势。如果您不打算推出自己的子类(可能会咬掉一点),您可以使用 UIPanGestureRecognizer 正如@Lyndsey 的回答所表明的那样。在那之后(在 cmets 中)我一直在寻找的是如何制作轻弹部分,其中轻弹的动量有助于决定是通过轻弹的动作还是恢复到原始演示文稿。

UIScrollView 具有类似的行为,并且很想挖掘它的实现以获取有关如何以一致的方式减速动量的详细信息,但是为 UIScrollView 提供的 decelerationRate 是“每次迭代”值(根据对一些)。我不知道如何正确地将默认值 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
        ...
    

【问题讨论】:

是的,如果您希望“滑动”的特定速度、角度、变化等来触发动画,请使用UIPanGestureRecognizerUISwipeGestureRecognizer 确实是一个独立的手势...类似于 UITapGestureRecognizer 叹息。有没有关于如何正确模拟方向过滤和速度的文档? 仅供参考,我在下面的答案中发布了指向文档的链接。 【参考方案1】:

是的,如果您想要“滑动”的特定速度、角度、变化等来触发动画,请使用 UIPanGestureRecognizerUISwipeGestureRecognizer 确实是一个独立的手势;类似于UITapGestureRecognizer,它在识别时触发单个操作消息。

与物理学一样,UIPanGestureRecognizer 的“速度”将指示平移手势的速度和方向。以下是docs for velocityInView: method,它将帮助您计算不断变化的平移手势的水平和垂直分量(以每秒点数为单位)。

【讨论】:

我想知道我的滑动最终会在哪里。在Ended 事件发生时,我有当前位移以及速度。但我不知道用什么作为减速因子来计算最终速度将携带我的“多远”。 Apple 是否针对他们用于这些计算的内容发布任何内容? @TravisGriggs 你说的“会带我”是什么意思?你只想知道用户的手指在哪里结束吗?如果是这样,则无需进行任何计算。只需使用locationInView::developer.apple.com/library/ios/documentation/UIKit/reference/…: 不,它比locationInView: 更复杂一点。这只是告诉我滑动(平移)在哪里结束。鉴于我正在使用滑动来“分页”视图,我需要弄清楚在视图上滑动多远来决定是否足以前进到下一页。如果用户用力轻拂视图,则不仅仅是手指的移动,而是考虑到在抬起时滑动的速度,视图将移动多远。您可以通过 Apple 的滚动视图看到这一点。我希望得到一些提示,他们是如何做到这一点的。 哦,你在 UIScrollView 上滑动?只需在滚动完成后检查其内容偏移量即可找到其最终位置。 不,我没有在UIScrollView 上滑动。但我试图获得类似于UIScrollView 滑动与普通UIViewUIPanGestureRecognizer 的东西。

以上是关于如果我想跟踪运动,是不是必须使用 UIPanGestureRecognizer 而不是 UISwipeGestureRecognizer?的主要内容,如果未能解决你的问题,请参考以下文章

如何跟踪触摸时的手指运动以绘制平滑曲线?

使用卡尔曼滤波器跟踪圆周运动的机器人

iOS 设备在 3d 空间中的运动检测

运动跟踪与 Blob 跟踪

如何使用视频对物体进行运动跟踪? [关闭]

检测是不是禁用了 iOS 智能跟踪预防