简体   繁体   中英

UIImageView rotation animation in the touched direction

I have one UIImageView having an image of an arrow. When user taps on the UIView this arrow should point to the direction of the tap maintaing its position it should just change the transform. I have implemented following code. But it not working as expected. I have added a screenshot. In this screenshot when i touch the point upper left the arrow direction should be as shown.But it is not happening so.

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

 UITouch *touch=[[event allTouches]anyObject];
 touchedPoint= [touch locationInView:touch.view];
 imageViews.transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(rangle11));
 previousTouchedPoint = touchedPoint ;
}

- (CGFloat) pointPairToBearingDegrees:(CGPoint)startingPoint secondPoint:(CGPoint) endingPoint
{

 CGPoint originPoint = CGPointMake(endingPoint.x - startingPoint.x, endingPoint.y - startingPoint.y); // get origin point to origin by subtracting end from start
   float bearingRadians = atan2f(originPoint.y, originPoint.x); // get bearing in radians
float bearingDegrees = bearingRadians * (180.0 / M_PI); // convert to degrees
bearingDegrees = (bearingDegrees > 0.0 ? bearingDegrees : (360.0 + bearingDegrees)); // correct discontinuity
return bearingDegrees;
}

在此处输入图片说明

I assume you wanted an arrow image to point to where ever you touch, I tried and this is what i could come up with. I put an image view with an arrow pointing upwards (haven't tried starting from any other position, log gives correct angles) and on touching on different locations it rotates and points to touched location. Hope it helps ( tried some old math :-) )

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

    UITouch *touch=[[event allTouches]anyObject];
    touchedPoint= [touch locationInView:touch.view];
    CGFloat angle = [self getAngle:touchedPoint];
    imageView.transform = CGAffineTransformMakeRotation(angle);

}

-(CGFloat) getAngle: (CGPoint) touchedPoints
{
    CGFloat x1 = imageView.center.x;
    CGFloat y1 = imageView.center.y;

    CGFloat x2 = touchedPoints.x;
    CGFloat y2 = touchedPoints.y;

    CGFloat x3 = x1;
    CGFloat y3 = y2;

    CGFloat oppSide = sqrtf(((x2-x3)*(x2-x3)) + ((y2-y3)*(y2-y3)));
    CGFloat adjSide = sqrtf(((x1-x3)*(x1-x3)) + ((y1-y3)*(y1-y3)));

    CGFloat angle = atanf(oppSide/adjSide);
    // Quadrant Identifiaction
    if(x2 < imageView.center.x)
    {
        angle = 0-angle;
    }


    if(y2 > imageView.center.y)
    {
        angle = M_PI/2 + (M_PI/2 -angle);
    }
     NSLog(@"Angle is %2f",angle*180/M_PI);
    return angle;

}

-anoop4real

Given what you told me, I think the problem is that you are not resetting your transform in touchesBegan . Try changing it to something like this and see if it works better:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{

 UITouch *touch=[[event allTouches]anyObject];
 touchedPoint= [touch locationInView:touch.view];
 imageViews.transform = CGAffineTransformIdentity;
 imageViews.transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(rangle11));
 previousTouchedPoint = touchedPoint ;
}

Do you need the line to "remove the discontinuity"? Seems atan2f() returns values between +π to -π. Won't those work directly with CATransform3DMakeRotation() ?

What you need is that the arrow points to the last tapped point. To simplify and test, I have used a tap gesture (but it's similar to a touchBegan:withEvent:).

In the viewDidLoad method, I register the gesture :

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)];
[self.view addGestureRecognizer:tapGesture];
[tapGesture release];

The method called on each tap :

- (void)tapped:(UITapGestureRecognizer *)gesture
{
    CGPoint imageCenter = mFlecheImageView.center;
    CGPoint tapPoint = [gesture locationInView:self.view];

    double deltaY = tapPoint.y - imageCenter.y;
    double deltaX = tapPoint.x - imageCenter.x;
    double angleInRadians = atan2(deltaY, deltaX) + M_PI_2;

    mFlecheImageView.transform = CGAffineTransformMakeRotation(angleInRadians);
}

One key is the + M_PI_2 because UIKit coordinates have the origin at the top left corner (while in trigonometric, we use a bottom left corner).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM