-4

I'm trying to make a volume knob like this:

https://s-media-cache-ak0.pinimg.com/736x/29/b5/85/29b58559e3d8a09dcd7e1a47c700ca76.jpg

But I only want to use one finger, UIGestureRotate is great but only supports rotation with two fingers and I don't seem to find the solution for UIPan​Gesture​Recognizer to rotate as I want it to? Is there a simple way to simulate the second finger in rotategesture or do I have to calculate pan?

Eric Aya
  • 69,473
  • 35
  • 181
  • 253

1 Answers1

3

If you ignore gesture recognizers and override touches handlers on a view, you can use math to do this. With a little trig, take an arbitrary anchor point along an axis (say 9 o'clock on the knob), and your touches' locations on the plane with (0, 0) at the center of your knob. Say your anchor point is at (-3, 0) and your touch is at (-1, 1) for the sake of simplicity. Take the arctan of the change in y over the change in x, in this case arctan of 1/2, which is roughly 0.464 radians, or roughly 26.585 degrees. You would rotate your knob 26.6 degrees clockwise (in this case) from your anchor point to have your knob follow your touch. In Swift:

//Assume you have an anchor point "anchor" and a touch location "loc"
let radiansToRotate = atan2(loc.y - anchor.y, loc.x - anchor.x)
let rotateAnimation = CABasicAnimation(keyPath: "transform.rotation")
rotateAnimation.fromValue = 0.0
rotateAnimation.toValue = radiansToRotate
rotateAnimation.duration = 1.0 //the longer the duration, the "heavier" your knob

That rotate animation will make the knob "follow" your finger, the desired effect. For completeness' sake, in a very basic form, atan2 is a math function that protects you from undefined arctan values. You'll have to worry about rotation direction, possibly, if your values fluctuate wildly, so you may consider using a key frame animation for this (I'll leave this to you).

diatrevolo
  • 2,782
  • 26
  • 45