【发布时间】:2014-08-13 22:02:25
【问题描述】:
我正在制作一个可旋转的轮子控件。您可以拖动它的任何地方以通过它的中心点旋转控件。
它的行为不正确。它通常运行良好,但在旋转的某些部分,它开始向相反方向旋转一小段时间,然后又开始用您的手指旋转。 编辑:经过进一步测试,我意识到您无需将其旋转 360 度即可使其向错误的方向旋转。
一个可能不相关的问题是控件的移动速度似乎比您的手指慢。如果原始问题的解决方案不能解决这个问题,我会提出一个单独的问题。
我发布了example project。如果您希望自己重现项目,以下是代码步骤:
- 创建一个新的单一视图应用程序。
- 创建一个名为
NNReadyIndicator的新UIView子类(在Objective-C 中) - 将此代码复制并粘贴到 `NNReadyIndicator.m
#import "NNReadyIndicator.h"
@interface NNReadyIndicator ()
@property CGAffineTransform startTransform;
@property double originalAngle;
@end
@implementation NNReadyIndicator
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
// Drawing code
}
*/
#pragma mark tracking
- (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
CGPoint touchPoint = [touch locationInView:self];
[self setOriginalAngle:[NNReadyIndicator calculateAngleWithX1:touchPoint.x x2:self.center.x y1:touchPoint.y y2:self.center.y]];
[self setStartTransform:self.transform];
NSLog(@"BEGIN TRACKING | originalAngle: %f", self.originalAngle);
return YES;
}
- (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
CGPoint touchPoint = [touch locationInView:self];
double angle = [NNReadyIndicator calculateAngleWithX1:touchPoint.x x2:self.center.x y1:touchPoint.y y2:self.center.y];
CGFloat angleDifference = (CGFloat)(self.originalAngle - angle);
[self setTransform: CGAffineTransformRotate(self.startTransform, -angleDifference)];
NSLog(@"CONTINUE TRACKING | angle: %f angleDifference: %f", angle, angleDifference);
return YES;
}
#pragma mark -- Calculate Angle
+ (double)calculateAngleWithX1:(double)x1 x2:(double)x2 y1:(double)y1 y2:(double)y2 {
double distanceX = [NNReadyIndicator calculateDistanceWithPoint:x1 point:x2];
double distanceY = [NNReadyIndicator calculateDistanceWithPoint:y1 point:y2];
return [self calculateAngleWithDistanceX:distanceX distanceY:distanceY];
}
+ (double)calculateDistanceWithPoint:(double)pointA point:(double)pointB {
double distance = pointA - pointB;
if (distance < 0) {
distance = -distance;
}
return distance;
}
+ (double)calculateAngleWithDistanceX:(double)distanceX distanceY:(double)distanceY {
return atan2(distanceY, distanceX);
}
@end
编辑:添加日志记录
为什么控件的旋转方向与拖动它的手指不同?
【问题讨论】:
-
我发现动画是懒惰的。当从角度 A 旋转到角度 B 时,它会想走最短的路线。即,如果旋转超过 180 度,它将想要“向后”。我通过做两次旋转一半来解决这个问题。
-
@HotLicks 好的,我搞定了。你想发布答案,还是我应该?
-
都是你的——反正我真的不知道我在说什么。
标签: ios rotation transform cgaffinetransform uicontrol