2012-05-13 9 views
6

Soy nuevo en el uso de transformaciones. Y todavía confían en cómo están trabajando.¿Por qué después de rotar el tamaño de UIImageView se está cambiando?

Lo que intento hacer es rotar mi UIImageView con un ángulo determinado. Pero después de rotar, está cambiando el tamaño de la imagen, haciéndose más pequeña. También estoy escalando para ImageView para que no esté al revés. Cómo rotar y mantener el tamaño, que se proporcionó en CGRectMake, cuando se asignó ImageView?

UIImageView *myImageView = [[UIImageView alloc]initWithFrame:CGRectMake(x,y,width,height)];   

    myImageView.contentMode = UIViewContentModeScaleAspectFit; 

    [myImageView setImage:[UIImage imageNamed:@"image.png"]]; 

    myImageView.layer.anchorPoint = CGPointMake(0.5,0.5); 

    CGAffineTransform newTransform; 

    myImageView.transform = CGAffineTransformMakeScale(1,-1);    

    newTransform = CGAffineTransformRotate(newTransform, 30*M_PI/180); 

    [self.window addSubview:myImageView]; 

¡Muchas gracias!

+0

¿Qué está cambiando realmente? ¿Estás hablando de que el marco de UIImageView cambia? ¿O es un cambio visible del tamaño de la imagen? ¿Cómo confirmaste el cambio? Si gira una vista, su marco siempre cambiará, ya que el marco representa el espacio de la vista dentro de su supervista. Los límites de la vista girada serán los mismos. –

+0

¿Hay algún código en touchesBegan: – MCKapur

+0

@JohannesLumpe Cambiando la imagen de Weidht, y probablemente la altura también. Sí, es un cambio visible, porque la imagen se está haciendo mucho más pequeña, luego estaba antes de girar, con el mismo tamaño dado de ImageView. – User1234

Respuesta

15

Ok, prometí que investigaría, así que aquí está mi respuesta:

Creo un escenario e que debe ser algo equivalente a la suya, el código de la siguiente manera:

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(self.view.bounds.size.width/2-100, 
                     self.view.bounds.size.height/2-125, 
                     200, 
                     250)]; 

imageView.image = [UIImage imageNamed:@"testimage.jpg"]; 
imageView.contentMode = UIViewContentModeScaleAspectFill; 

/* 
* I added clipsToBounds, because my test image didn't have a size of 200x250px 
*/ 
imageView.clipsToBounds = YES; 

[self.view addSubview:imageView]; 

NSLog(@"frame: %@",[NSValue valueWithCGRect:imageView.frame]); 
NSLog(@"bounds: %@",[NSValue valueWithCGRect:imageView.bounds]);  

imageView.layer.anchorPoint = CGPointMake(0.5, 0.5); 
imageView.transform = CGAffineTransformMakeRotation(30*M_PI/180); 

NSLog(@"frame after rotation: %@",[NSValue valueWithCGRect:imageView.frame]); 
NSLog(@"bounds after rotation: %@",[NSValue valueWithCGRect:imageView.bounds]); 

Este código se supone que está utilizando ARC. Si no agrega

[imageView release]; 

al final.

Utilizando este código los registros de un aspecto como este:

[16221:207] frame: NSRect: {{60, 105}, {200, 250}} 
[16221:207] bounds: NSRect: {{0, 0}, {200, 250}} 
[16221:207] frame after rotation: NSRect: {{10.897461, 71.746826}, {298.20508, 316.50635}} 
[16221:207] bounds after rotation: NSRect: {{0, 0}, {200, 250}}  

Como se puede ver los límites siempre permanecen igual. Lo que realmente cambia debido a la rotación es el marco, porque una imagen que ha sido rotada en 30 ° C es, por supuesto, más ancha que si no hubiera sido rotada. Y como el punto central se ha establecido en el centro real de la vista, el origen del marco también cambia (se empuja hacia la izquierda y hacia arriba). Tenga en cuenta que el tamaño de la imagen en sí no cambia. No usé la transformación de escala, ya que el resultado se puede lograr sin escalar.

pero para que sea más claro aquí hay algunas fotos para ti (0 °, 30 ° 90 ° de rotación): 0°,30° and 90° rotations of UIImageView

Ya ven bastante similares, ¿verdad? Dibujé los cuadros reales para dejar en claro cuál es la diferencia entre los límites y el marco. El siguiente realmente lo deja en claro. Sobrepuse todas las imágenes, girándolas por los grados negativos con los que se giró el UIImageView, obteniendo el siguiente resultado: UIImageViews overlayed to show that size doesn't change

Así que como ve, es bastante sencillo cómo rotar las imágenes. Ahora a su problema que realmente quiere que el marco permanezca igual. Si desea que el fotograma final tenga el tamaño de su fotograma original (en este ejemplo con un ancho de 200 y una altura de 250), tendrá que escalar el fotograma resultante. Pero esto, por supuesto, dará como resultado la ampliación de la imagen, que no desea.De hecho, creo que un marco más grande no será un problema para ti, solo necesitas saber que debes tenerlo en cuenta debido a la rotación.

En resumen: no es posible tener un UIImageView que tendrá el mismo marco después de la rotación. Esto no es posible para ningún UIView. Solo piensa en un rectángulo. Si lo gira, no será un rectángulo después de la rotación, ¿verdad?

Por supuesto, puede colocar su UIImageView dentro de otra UIView que tendrá un marco no girado con un ancho de 200 y una altura de 250, pero eso sería superficial, ya que no cambiará el hecho de que una el rectángulo girado tiene un ancho y altura diferente que el original.

Espero que esto ayude. :)

+0

Hay una función 'NSStringFromCGRect()' que puede ser un poco más fácil que envolver cosas en 'NSValue' como' [NSValue valueWithCGRect: imageView.bounds] ' –

+0

¡Gracias por señalar eso, necesitamos escribir eso! –

+2

Hay una gran cantidad de estas útiles [funciones de UIKit] (http://developer.apple.com/library/ios/#documentation/uikit/reference/UIKitFunctionReference/Reference/reference.html) –

0

No configure el modo de contenido que UIImageView hereda de UIView y conduce a los cambios en el marco de acuerdo con la escala, la transformación, la rotación del dispositivo de acuerdo con el UIViewContentMode que seleccione.

Además, si lo que desea es gire sólo puede cambiar el marco usando: -

[UIView beginAnimations:@"Rotate" context:nil]; 
    [UIView setAnimationDuration:1.0]; 
    [UIView setAnimationDelegate:self]; 
    CGRect frame=yourView.frame; 
    frame.origin.y+=distance you want to rotate; 
    yourview.frame=frame; 
    [UIView commitAnimations]; 
} 

si no quieres que la animación sólo cambia el marco

Trate de usar este: -

CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
animation.fromValue = [NSNumber numberWithFloat:0.0f]; 
animation.toValue = [NSNumber numberWithFloat: 2*M_PI]; 
animation.duration = 0.5f;    
animation.repeatCount = HUGE_VALF;  // HUGE_VALF is defined in math.h so import it 
[self.reloadButton.imageView.layer addAnimation:animation forKey:@"rotation"]; 
+0

Lo estoy usando, por lo que mi imagen no perderá la relación de aspecto. Si lo elimino, no lo mantendrá, y la imagen no se verá bien. – User1234

+0

Gracias por la respuesta, pero todavía estoy confundido. Solo quiero rotar manualmente ImageView con un ángulo determinado. Y quiero mantener la relación de aspecto, para que la imagen se vea correcta. Más claro: quiero que la imagen tenga el mismo tamaño, que era antes de GIRAR, con límites dados. Así que rotar no cambiará su altura/peso. ¿Es posible? – User1234

+0

lo que puede hacer es rotar la imagen y luego escalarla al original –

Cuestiones relacionadas