旋转拨盘 – 旋转限制

我正在制作一个老式手机,并获得了一个正常工作的起始码,用户将手指移过UIImageView数字并旋转拨号。 然后它将其移回原始位置。 见截图。

在此处输入图像描述

我似乎无法弄清楚的三个问题是:

  1. 如何限制用户仅按顺时针方向旋转? 目前用户可以向任何方向移动(顺时针和逆时针)

  2. 如何检测用户选择的号码? 意味着用户触及1或3或5? 我需要这个信息,以便当该数字到达右边的栏时我可以停止旋转。

  3. 在我当前的代码中,当我停止旋转并放开圆圈时,它通过逆时针向后移动回到它的位置。 如果我选择1,2,3,4,它可以正常工作,但对于任何数字5及以上,表盘顺时针移动回原位。 如何在touchesEnded上强制逆时针运动?

我们假设您正在谈论这个姿势:

旋转拨号 来源 。


构建单点触摸旋转手势识别器。 正确构建手势识别器后,您只需查看旋转,看看如何处理旋转垫。

在构建单点触控旋转手势识别器时,您会考虑几件事。 如果您查看UIRotationGestureRecognizer ,它会使用两个手指支持的两个触摸之间的连接来获取当前角度,然后将角度与先前角度(从早期的触摸更改事件派生)进行比较,以查看增量。

测量当前角度

形成一条线需要两个点,你需要一条线才能知道角度。 如果您只使用一次触摸,则需要一个锚点。 有很多方法可以将锚点发送到手势识别器,并且由于您可能要构建自定义类,因此请使用委托。

累积轮换计数

如果您只是记录角度并在触摸更改期间发送消息,它有时会起作用。 但是,如果您想要实现滞后(例如,此旋转拨盘只能顺时针旋转一次,然后它会收紧),您需要累计顺时针和逆时针方向的旋转计数。

幸运的是,您可以假设a)触摸事件不会经常掉落,并且b)简单地将当前角度与过去角度进行比较,看看它们是否越过象限边界就足够了。

例如:

  • 如果触摸从左上象限移动到右上象限,则向旋转计数添加一个。
  • 如果触摸从右上象限移动到左上象限,则从旋转计数中减去一个。

(是的,这确实有效。)

发出正确的累积旋转

如果您想要像UIRotationGestureRecognizer一样发出旋转信息,那么您将跟踪四件事。

  1. 起始角度:从锚点到起始触摸的连接与从锚点到固定参考点的连接之间的角度。
  2. 当前角度:从锚点到当前触摸的连接与从锚点到固定参考点的连接之间的角度。
  3. 旋转计数:从连续比较当前角度的当前值与其最后一个值得到的顺时针旋转次数(如上一节所述)。 如果触摸逆时针移动,则此计数将变为负数。

您将提供Rotation Count * 2_PI + (Current Angle - Starting Angle)作为旋转。

好的,我会采取不同的方法。 首先,您要创建一个RotaryDial类来封装所有行为。 然后您可以根据需要将其插入任何视图。

为了简单RotaryDialDigit ,我会考虑将每个数字按钮设置为可移动的UIImageView,将其RotaryDialDigit或类似的东西。 您将实例化并放置其中的十个。

当用户移动其中一个RotaryDialDigit按钮时,表盘“框架”将标记为骑行。 它只是一个图像(除非您希望用户能够触摸它并使用它做一些事情。

从那里,知道哪个按钮被按下并将其旋转限制在给定方向以及停在酒吧是相当容易的事情。

通过使用协议,您可以让RotaryDial实例在拨打号码时告诉容器。 容器RotaryDial就像每次按下按钮时发送消息的键盘。 你真的不希望容器打扰除完成的数字选择之外的任何东西。

要检测触摸的数字,在创建每个数字时,应设置其UIView的tag值。 然后,当用户触摸该数字时,您可以通过检查该标记值来检测它是哪个UIView对象。

对于旋转问题,我建议看看你是如何计算角度的。 我想对于大于4的数字(你从标签中辨别出来),你需要做一些事情,比如从360度(2Pi)减去你当前正在计算的角度。 (但我现在头冷,所以实际数学逃避了我:-))

在没有看到你的代码的情况下,我假设这些数字是静态图像,并且当它们旋转超过每个数字时,你可以设置手指孔的动画。 如果是这样:

检测哪个数字:定义每个按钮周围的CGRect。 当用户点击屏幕时,检查哪个矩形包含点击位置。

控制旋转方向:当用户拖动手指时,可以连续计算从拨号停止位置到当前抽头位置的角度。 如果角度向错误的方向移动,则不要更新指孔的位置。 请注意,trig函数将vales从+ Pi返回到-Pi弧度。 对于大于5的数字,您可能希望将2Pi弧度(或360度)添加到角度,而不是处理负角度。

旋错方式:低于5的数字是0到-Pi范围内的生成角度。 没有看到代码,我怀疑在角度上添加2Pi会纠正您的旋转方向。

这是一个更好的表盘:

在此处输入图像描述

玩的开心!