使用 CGAffineTransformRotate 旋转视图

发布于 2024-09-11 17:59:37 字数 695 浏览 4 评论 0 原文

我有一个正在尝试旋转的圆形图像,以便黄色和黑色条纹圆圈留在用户的手指下并在两个方向上旋转。到目前为止我有这个:

- (void)handleJogShuttle:(UIPanGestureRecognizer *)recognizer {

    UIView *shuttle = [recognizer view];

    if ([recognizer state] == UIGestureRecognizerStateBegan ||
        [recognizer state] == UIGestureRecognizerStateChanged) {

        [recognizer view].transform = CGAffineTransformRotate([[recognizer view] transform],M_PI / 20.0f);
        [recognizer setTranslation:CGPointZero inView:[shuttle superview]];
    }
}

此外,目前,最轻微的移动都会导致视图旋转一整圈,这显然是不希望的。

I have a circular image which I am trying to rotate, so that the yellow and black striped circle stays under the user's finger and rotates in both directions. I have this so far:

- (void)handleJogShuttle:(UIPanGestureRecognizer *)recognizer {

    UIView *shuttle = [recognizer view];

    if ([recognizer state] == UIGestureRecognizerStateBegan ||
        [recognizer state] == UIGestureRecognizerStateChanged) {

        [recognizer view].transform = CGAffineTransformRotate([[recognizer view] transform],M_PI / 20.0f);
        [recognizer setTranslation:CGPointZero inView:[shuttle superview]];
    }
}

Also, currently, the slightest movement can cause the view to rotate in a full circle, which is obviously not desired.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

寄居者 2024-09-18 17:59:37
#import "RotationTestViewController.h"

@interface RotationTestViewController()
-(void)transformSpinnerwithTouches:(UITouch *)touchLocation;
-(CGPoint)vectorFromPoint:(CGPoint)firstPoint toPoint:(CGPoint)secondPoint;
-(void)animateView:(UIView *)theView toPosition:(CGAffineTransform) newTransform;
@end
@implementation RotationTestViewController

- (void)viewDidLoad {
[super viewDidLoad];}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    for (UITouch *touch in touches)
    {
        // Send to the dispatch method, which will make sure the appropriate subview is acted upon
        //    currentTouch=touch;
    }
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    for (UITouch *touch in touches){
        // Sends to the dispatch method, which will make sure the appropriate subview is acted upon
    }
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch=[[event allTouches]anyObject];
    if (touch.view==Spinner)
    {
        [self transformSpinnerwithTouches:touch];
    }
}

-(void)transformSpinnerwithTouches:(UITouch *)touchLocation
{
    CGPoint touchLocationpoint = [touchLocation locationInView:self.view];
    CGPoint PrevioustouchLocationpoint = [touchLocation previousLocationInView:self.view];
    //origin is the respective piont from that i gonna measure the angle of the current position with respective to previous position ....
    CGPoint origin;
    origin.x=Spinner.center.x;
    origin.y=Spinner.center.y;
    CGPoint previousDifference = [self vectorFromPoint:origin toPoint:PrevioustouchLocationpoint];
    CGAffineTransform newTransform =CGAffineTransformScale(Spinner.transform, 1, 1);
    CGFloat previousRotation = atan2(previousDifference.y, previousDifference.x);
    CGPoint currentDifference = [self vectorFromPoint:origin toPoint:touchLocationpoint];
    CGFloat currentRotation = atan2(currentDifference.y, currentDifference.x);
    CGFloat newAngle = currentRotation- previousRotation;
    temp1=temp1+newAngle;
    NSLog(@"Angle:%F\n",(temp1*180)/M_PI);
    newTransform = CGAffineTransformRotate(newTransform, newAngle);
    [self animateView:Spinner toPosition:newTransform];
}

-(void)animateView:(UIView *)theView toPosition:(CGAffineTransform) newTransform
{
    [UIView setAnimationsEnabled:YES];
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationCurve:UIViewAnimationCurveLinear];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:0.0750];
    Spinner.transform = newTransform;
    [UIView commitAnimations];
}

//-(CGFloat)distanceFromPoint:(CGPoint)fromPoint toPoint:(CGPoint)toPoint
//
//{
//float x = toPoint.x - fromPoint.x;
//float y = toPoint.y - fromPoint.y;
//return hypot(x, y);
//}

-(CGPoint)vectorFromPoint:(CGPoint)firstPoint toPoint:(CGPoint)secondPoint
{
    CGFloat x = secondPoint.x - firstPoint.x;
    CGFloat y = secondPoint.y - firstPoint.y;
    CGPoint result = CGPointMake(x, y);
    //NSLog(@"%f %f",x,y);
    return result;
}

-(void) dealloc
{
    [Spinner release];
    [super dealloc];
}
#import "RotationTestViewController.h"

@interface RotationTestViewController()
-(void)transformSpinnerwithTouches:(UITouch *)touchLocation;
-(CGPoint)vectorFromPoint:(CGPoint)firstPoint toPoint:(CGPoint)secondPoint;
-(void)animateView:(UIView *)theView toPosition:(CGAffineTransform) newTransform;
@end
@implementation RotationTestViewController

- (void)viewDidLoad {
[super viewDidLoad];}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    for (UITouch *touch in touches)
    {
        // Send to the dispatch method, which will make sure the appropriate subview is acted upon
        //    currentTouch=touch;
    }
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    for (UITouch *touch in touches){
        // Sends to the dispatch method, which will make sure the appropriate subview is acted upon
    }
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch=[[event allTouches]anyObject];
    if (touch.view==Spinner)
    {
        [self transformSpinnerwithTouches:touch];
    }
}

-(void)transformSpinnerwithTouches:(UITouch *)touchLocation
{
    CGPoint touchLocationpoint = [touchLocation locationInView:self.view];
    CGPoint PrevioustouchLocationpoint = [touchLocation previousLocationInView:self.view];
    //origin is the respective piont from that i gonna measure the angle of the current position with respective to previous position ....
    CGPoint origin;
    origin.x=Spinner.center.x;
    origin.y=Spinner.center.y;
    CGPoint previousDifference = [self vectorFromPoint:origin toPoint:PrevioustouchLocationpoint];
    CGAffineTransform newTransform =CGAffineTransformScale(Spinner.transform, 1, 1);
    CGFloat previousRotation = atan2(previousDifference.y, previousDifference.x);
    CGPoint currentDifference = [self vectorFromPoint:origin toPoint:touchLocationpoint];
    CGFloat currentRotation = atan2(currentDifference.y, currentDifference.x);
    CGFloat newAngle = currentRotation- previousRotation;
    temp1=temp1+newAngle;
    NSLog(@"Angle:%F\n",(temp1*180)/M_PI);
    newTransform = CGAffineTransformRotate(newTransform, newAngle);
    [self animateView:Spinner toPosition:newTransform];
}

-(void)animateView:(UIView *)theView toPosition:(CGAffineTransform) newTransform
{
    [UIView setAnimationsEnabled:YES];
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationCurve:UIViewAnimationCurveLinear];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDuration:0.0750];
    Spinner.transform = newTransform;
    [UIView commitAnimations];
}

//-(CGFloat)distanceFromPoint:(CGPoint)fromPoint toPoint:(CGPoint)toPoint
//
//{
//float x = toPoint.x - fromPoint.x;
//float y = toPoint.y - fromPoint.y;
//return hypot(x, y);
//}

-(CGPoint)vectorFromPoint:(CGPoint)firstPoint toPoint:(CGPoint)secondPoint
{
    CGFloat x = secondPoint.x - firstPoint.x;
    CGFloat y = secondPoint.y - firstPoint.y;
    CGPoint result = CGPointMake(x, y);
    //NSLog(@"%f %f",x,y);
    return result;
}

-(void) dealloc
{
    [Spinner release];
    [super dealloc];
}
稀香 2024-09-18 17:59:37

我怀疑这个方法被多次调用。尝试使用 NSLog 并检查它执行了多少次。
无论如何,您没有正确计算角度,您可以尝试使用

-(CGPoint)translationInView:(UIView *)view

识别器来计算正确的旋转角度。

I suspect this method gets called A LOT. Try using NSLog and check how many time it does.
Anyway, you are not calculating the angle properly, you could try using

-(CGPoint)translationInView:(UIView *)view

from the recognizer to calculate the correct angle to rotate.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文