ios - UIImageView animación de rotación en la dirección tocada
cocoa-touch transform (4)
Tengo un UIImageView que tiene una imagen de una flecha. Cuando el usuario toca en el UIView, esta flecha debe apuntar a la dirección del tap que mantiene su posición, solo debería cambiar la transformación. He implementado el siguiente código. Pero no funciona como se esperaba. He agregado una captura de pantalla. En esta captura de pantalla, cuando toco el punto superior izquierdo, la dirección de la flecha debe ser como se muestra. Pero no está sucediendo así.
-(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;
}
¿Necesitas la línea para "eliminar la discontinuidad"? Parece que atan2f()
devuelve valores entre + π a -π. ¿No funcionarán directamente con CATransform3DMakeRotation()
?
Dado lo que me dijiste, creo que el problema es que no estás restableciendo tu transformación en touchesBegan
. Intente cambiarlo a algo así y vea si funciona mejor:
-(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 ;
}
Lo que necesitas es que la flecha apunte al último punto tocado. Para simplificar y probar, he usado un gesto tap (pero es similar a un touchBegan: withEvent :).
En el método viewDidLoad, registro el gesto:
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)]; [self.view addGestureRecognizer:tapGesture]; [tapGesture release];
El método llamado en cada toque:
- (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); }
Una clave es + M_PI_2
porque las coordenadas UIKit tienen el origen en la esquina superior izquierda (mientras que en trigonométrico, usamos una esquina inferior izquierda).
Supongo que querías que una imagen de flecha indicara dónde tocas, lo intenté y esto es lo que podría hacer. Puse una vista de imagen con una flecha apuntando hacia arriba (no he intentado comenzar desde cualquier otra posición, el registro proporciona ángulos correctos) y al tocar en diferentes ubicaciones, gira y apunta a la ubicación tocada. Espero que ayude (intenté algunas matemáticas antiguas :-))
-(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