I am wondering what is the best way to implement rotation-based dragging movements in my iPhone application.
I have a UIView that I wish to rotate around its centre,
Have you considered using UIRotationGestureRecognizer
? Seems like that has the logic already baked in, and might make things simpler.
It is actually much simpler than what you have tried.
You need three data points:
The Touch object passed to you actually contains the last touch location. So you don't need to keep track of it.
All you have to do is calculate the angle between two lines:
Then convert that to radians and use that in your CGAffineTransformRotate(). Do that all in your touchesMoved handler.
Here is a function to calculate what you need just that:
static inline CGFloat angleBetweenLinesInRadians(CGPoint line1Start, CGPoint line1End, CGPoint line2Start, CGPoint line2End) {
CGFloat a = line1End.x - line1Start.x;
CGFloat b = line1End.y - line1Start.y;
CGFloat c = line2End.x - line2Start.x;
CGFloat d = line2End.y - line2Start.y;
CGFloat line1Slope = (line1End.y - line1Start.y) / (line1End.x - line1Start.x);
CGFloat line2Slope = (line2End.y - line2Start.y) / (line2End.x - line2Start.x);
CGFloat degs = acosf(((a*c) + (b*d)) / ((sqrt(a*a + b*b)) * (sqrt(c*c + d*d))));
return (line2Slope > line1Slope) ? degs : -degs;
}
Courtesy of Jeff LaMarche at:
http://iphonedevelopment.blogspot.com/2009/12/better-two-finger-rotate-gesture.html
Example:
UITouch *touch = [touches anyObject];
CGPoint origin = [view center];
CGFloat angle = angleBetweenLinesInRadians(origin, [touch previousLocationInView:self.superview.superview], origin, [touch locationInView:self.superview.superview]);