iOS/Swift:检测旋转运动的自定义 UIGestureRecognizer

iOS/Swift: Custom UIGestureRecognizer that detect spin motion

嘿,我正在尝试构建一个允许我在屏幕上旋转轮子的 UIGestureRecognizer。想象一下:

必须检测两个手势:转动轮子和旋转轮子。 我已经完成了构建一个 UIGestureRecognizer 识别转动轮子,换句话说,旋转它。我还能够将 UISwipeGestureRecognizer 添加到滚轮以检测是否发生了旋转手势。但是,我还希望检测到如下所示的手势:

  1. 用户通过在屏幕上平移来旋转滚轮
  2. 平移后,手指仍放在屏幕上,快速滑动并移开屏幕手指,滚轮会旋转

我试过使用

public func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool { return true }

让它们同时工作,但没有成功。此外,我认为仅仅连接两个描述的 GestureRecognizers 是行不通的。

如有任何帮助,我将不胜感激。谢谢

你的问题是,当平移开始时,它将继续被识别为平移手势,直到触摸结束。所以你需要弄清楚的是平移结束时的速度,如果你想变得更漂亮,将那个速度从相对于视图中心的点投影到垂直向量上。这将涉及一些三角函数,我完全忘记了,但它看起来像这样。

func pan(_ sender: UIPanGestureRecognizer) {
        ...

     if sender.state == .ended {
        let loc = sender.location(in: sender.view)
        let midpoint = CGPoint(x: sender.view!.bounds.width/2, y: sender.view!.bounds.height/2)
        let v = sender.velocity(in: sender.view)
        let p = CGPoint(x: midpoint.x - loc.x, y: midpoint.y - loc.y)

        let angle = atan(p.y/p.x)
        print(angle)
        let vProjection = v.y * cos((CGFloat.pi/2 - angle)) + v.x * cos(angle)
        print("moment: ", vProjection)

        let torque = p.hypotenuse() * vProjection
        wheel.rotate(with: torque)
    }
}

extension CGPoint {
    func hypotenuse() -> CGFloat {
        return sqrt(self.x * self.x + self.y * self.y)
    }
}

我想我的三角函数有错误。我将不得不画一些图表,但它给出了总体思路。 wheel.rotate(使用力矩:CGFloat)将 运行 层的变换动画以旋转它..