Я немного боролся с тем, как получить вращение, управляемое касанием, тем более, потому что я хочу на 100% понять код, который я использую. Так что после многих неудачных попыток я закончил так:
- (CGFloat) pointToAngleFromCenter: (CGPoint) point {
// transform point to a self.center'ed origin based coordinate system
point.x = point.x - self.center.x ;
// ditto for y, but compensate for y going downwards to y going upwards
point.y = self.center.y - point.y ;
return ::atan2(point.y, point.x) ;
}
Если у кого-то есть более подходящее название для этого метода, я весь в ушах.
Что он делает, так это то, что он берет точку в координатах родительского вида, сопоставляет ее относительно центра вида (которая находится в координате родительского вида) и вычисляет угол между этой переназначенной точкой и осью [0X]. Для этого он нормализует y к нормальным математическим координатам (y увеличивается, когда его значение увеличивается, а не уменьшается), следовательно, self.center.y - point.y
, а не наоборот.
Наконец-то в касанияхMoved:
- (void) touchesMoved: (NSSet *) touches withEvent: (UIEvent *) event {
UITouch * touch = [touches anyObject] ;
CGFloat currA = [self pointToAngleFromCenter:[touch locationInView:self.superview]] ;
CGFloat prevA = [self pointToAngleFromCenter:[touch previousLocationInView:self.superview]] ;
// the current value of the rotation angle
CGFloat tranA = ::atan2(self.transform.b, self.transform.a) ;
// the angle difference between last touch and the current touch
CGFloat diffA = currA - prevA ;
// the new angle resulting from applying the difference
CGFloat angle = tranA - diffA ;
CGAffineTransform t = ::CGAffineTransformMakeRotation(angle) ;
self.transform = t ;
[self setNeedsDisplay] ;
}