Aplicando escala y rotation en una vista usando CGAffineTransform

Entonces, necesito aplicar un poco de escala y algo de rotation a una vista (lo hago usando gestos), así que para cada gesto actualizo los valores actuales de escalamiento y rotation con algo como:

self.scaleWidth *= gesture.scale; //When I detect an horizontal pinch self.scaleHeight *= gesture.scale; //When I detect a vertical pinch self.rotationAngle += gesture.rotationAngle; //When I detect a rotation 

Luego hago lo siguiente para transformar la vista:

 CGAffineTransform transform = CGAffineTransformScale(CGAffineTransformIdentity, self.scaleWidth, self.scaleHeight); self.theSubViewToTransform.transform = CGAffineTransformRotate(transform, self.rotationAngle); 

Cuando solo hago escala, funciona bien. Cuando hago escala y gire, gira bien. Cuando después de rotar bash escalar de nuevo, no funciona bien: la escala se aplica como si se hubiese realizado después de la rotation, deformando la estructura de mi image.

Pensé que hice lo que había que hacer para evitar esto: comenzar cada vez desde una transformación de identidad, escalar primero y luego rotar, pero obviamente estaba equivocado …

¿Alguien sabe qué está mal con mi implementación?

Gracias

Si comienza con la transformación de identidad cada vez, el resultado final al que está configurando la transformación de la subvista solo includeá la escala y la rotation del gesto actual. En lugar de comenzar con la identidad, comience con la transformación actual de la vista.

 CGAffineTransform transform = self.theSubViewToTransform.transform; transform = CGAffineTransformScale(transform, self.scaleWidth, self.scaleHeight); transform = CGAffineTransformRotate(transform, self.rotationAngle); self.theSubViewToTransform.transform = transform; 

La primera vez que esto se ejecuta, la transformación comenzará como la identidad se transforma. En ejecuciones posteriores, hará que los nuevos cambios sobre los anteriores.

Debe comenzar desde su estado transformado actual y aplicar la transformación que se espera. También puedes echar un vistazo a CGAffineTransformConcat , lo convertirá en una única transformación antes de aplicar.

 CGAffineTransform transform = yourView.transform; transform = CGAffineTransformConcat(CGAffineTransformScale(transform, self.scaleWidth, self.scaleHeight), CGAffineTransformRotate(transform, self.rotationAngle)); yourView.transform = transform; 

¡Espero eso ayude!

Prueba aplicar las transformaciones a la transformación de identidad, por ejemplo

 CGAffineTransform transform = CGAffineTransformIdentity; transform = CGAffineTransformScale(transform, scaleWidth, scaleHeight); transform = CGAffineTransformRotate(transform, angle); viewToTransform.transform = transform; 

Para swift 3 :

 view.transform = CGAffineTransform(rotationAngle: CGFloat.pi).concatenating(CGAffineTransform(scaleX: 0.4, y: 0.4))