ios - Gire UIView alrededor de su centro manteniendo su tamaño
objective-c rotation (8)
Estoy intentando rotar un UIView
unos pocos radianes, pero después de aplicar la transformación no parece mantener su tamaño. ¿Cuál es la forma correcta de lograr esto?
Esto es lo que estoy haciendo y lo que obtengo (el cuadro azul con la flecha es la vista que trato de rotar, debe mantener el mismo aspecto que el cuadro rojo detrás):
#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
double rads = DEGREES_TO_RADIANS(240);
CGAffineTransform transform = CGAffineTransformRotate(CGAffineTransformIdentity, rads);
self.arrowView.transform = transform;
¡Gracias!
Actualiza la respuesta de Luca Davanzo con Swift 4:
/**
Rotate a view by specified degrees
- parameter angle: angle in degrees
*/
func rotate(angle: CGFloat) {
let radians = angle / 180.0 * CGFloat.pi
let rotation = self.transform.rotated(by: radians)
self.transform = rotation
}
En Swift 3:
let degrees: CGFloat = -90
let radians = CGFloat(__sinpi(degrees.native/180.0))
view.transform = CGAffineTransform(rotationAngle: radians)
Estoy usando -90
debido a esta parte específica de la documentación sobre el rotationAngle
que debe pasar a CGAffineTransform
:
El ángulo, en radianes, por el cual esta matriz gira los ejes del sistema de coordenadas. En iOS, un valor positivo especifica la rotación en sentido antihorario y un valor negativo especifica la rotación en el sentido de las agujas del reloj.
En mi opinión, necesitas calcular el centro de tu triángulo y rotar alrededor de este punto. Ahora giras la flecha alrededor del centro de tu cuadrado.
Ver: ¿ Transformación afín de un paso para la rotación alrededor de un punto?
Espero que te ayude.
Evito usar macros a menos que sea necesario. Esto funciona perfectamente bien
float degrees = 20; //the value in degrees
view.transform = CGAffineTransformMakeRotation(degrees * M_PI/180);
La transformación CGAffineTransformRotate
gira desde una transformación afín existente. El hecho de que esté utilizando CGAffineTransformIdentity
podría ser el problema. Debe especificar la transformación actual de su vista.
#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
...
double rads = DEGREES_TO_RADIANS(240);
CGAffineTransform transform = CGAffineTransformRotate(self.arrowView.transform, rads);
self.arrowView.transform = transform;
Además, es posible que desee considerar:
self.arrowView.transform = CGAffineTransformMakeRotation(rads);
EDITAR : Si puedes, comparte qué tipo de transformación (animada / inanimada, única / iterativa) quieres lograr. Creo que podría haber una manera mejor y optimizada de hacer esto.
Probablemente estés solucionando un problema con Autolayout. Probablemente tenga restricciones en la vista girada que lo fija a los bordes de la supervista. Cuando se aplica la transformación, Autolayout está actualizando el tamaño de la vista para que encaje dentro de la supervista.
Puede experimentar con diferentes restricciones (por ejemplo, fijando el centro de la vista en el centro de otra vista, y fijando el ancho y el alto en valores constantes) o desactivando el Autolayout para la vista girada, o si estos no funcionan o no se ponen Se adapta a sus necesidades, use una vista de contenedor que se encuentra en Autolayout y agregue su vista giratoria a esto, sin usar Autolayout.
Esto solo se puede hacer en código: puede hacer que las vistas individuales estén sujetas a Autolayout o no, configurando tralationsAutoresizingMasksIntoConstraints en NO
(Autolayout activado) o YES
(Autolayout desactivado). Tendrá que configurar las máscaras de aumento automático adecuadas si cambia una vista de una a otra.
Pruebe con este código:
#define DEGREES_TO_RADIANS(angle) ((angle) / 180.0 * M_PI)
double rads = DEGREES_TO_RADIANS(240);
self.arrowView.layer.transform = CATransform3DMakeRotation(rads, 0, 0, 1);
¡Swift + extension son tus amigos!
// MARK: - UIView Extension -
extension UIView {
/**
Rotate a view by specified degrees
- parameter angle: angle in degrees
*/
func rotate(angle angle: CGFloat) {
let radians = angle / 180.0 * CGFloat.pi
let rotation = CGAffineTransformRotate(self.transform, radians);
self.transform = rotation
}
}
De esta forma, en cualquier parte de tu código:
let view = UIView(frame: CGRectMake(0, 0, 100, 100))
view.backgroundColor = UIcolor.redColor()
view.rotate(angle: 90)