Recreating same transform on UIImageView after pan/resize/rotate - ios

I have a problem which is causing me a 'headache' and hope someone out there can help me.
I have a UIView with a child UIImageView presented on top, containing an image.
Using gestures, I can pan, scale and rotate that image. During this process, the anchor point may change to ensure the scale/rotate is point between the two fingers of the gesture. CGAffineTransforms are used to achieve this and it works well.
My problem is storing and recreating the transforms when I destroy and recreate the enclosing view controller.
When I leave that view, I store the transform and frame...
-(CGAffineTransform)imageViewTransform
{
return self.testImageView.transform;
}
-(CGRect)imageViewFrame
{
return self.testImageView.frame;
}
....and when I recreate that view I set the frame and transform of my imageView...
self.imageView.transform = mySavedTransform;
self.imageView.frame = mySavedFrame;
This works and I can move and stretch my image, then recreate next time in.
However, if I rotate my image, the recreated image frame at the correct angle but is stretched and not at original coordinates, so I don't get exactly what I saved.
Setting the frame before the transform has the same undesired effect on rotations.
My question is why can't I recreate the exact scaled, rotated and positioned UIImageView using the above technique?
Surely reproducing the frame and transform would have the desired effect?
Is this the usual method for doing this, or am I missing something?
Any help appreciated.

For those interest, this is sorted.
The problem was the anchor-point which was not being stored, as well as using the center for recreation of the image. So, to faithfully reproduce a transformation, it appears you need to store the center, transform and anchor.
HTH

Related

Flipping image after rotation issue (need to do both, only does one)

I have a UIImage on my storyboard, and I have just rotated it( i can rotate it any number of degrees). The code for the rotation is below:
let DegreesFloat = Double(-Degrees) * M_PI/180
self.imageView.transform = CGAffineTransformMakeRotation(CGFloat(DegreesFloat))
By the way, degrees in the first line of code, is an integer I enter into a text field. When the view loads, I have this...
self.imageView.transform = CGAffineTransformMakeScale(1, -1);
to keep the image upside down, cause that's just how I need it to be. The issue is that when I rotate the image, it cancels out the flip, and flips it back to its original flip (without the 2nd paragraph of code). I need it to keep it's upside down flip, while performing it's rotation.
When I add the flip code after the rotate code, it just cancels out the rotate code. I have no idea how to do this, but I just need it to stay upside down, while correctly performing a rotation, and NOT flipping itself back to its original right-side up orientation.
I think what you are asking is how to make multiple transform commands together. The transformations are actually a matrix telling the image later what to do. Use a CGAffineTransformConcat to apply multiple transformations. Refer to the Apple documentation

How to rotate a view in place after transform as been applied?

I'm using a variant of this code to slighty rotate a UIButton about its center:
CGFloat jiggleAngle = (-M_PI * 2.0) * (1.0 / 64.0);
self.transform = CGAffineTransformRotate(self.transform, jiggleAngle);
This code generally works as expected and rotates the button in-place, about 12 degrees counter-clockwise. However, this only works if I do not reposition the button inside my layoutSubviews method. If I do any repositioning of the button at all from its initially laid-out location, the attempt to rotate above results in the button's disappearance. If the angle I choose for rotation is an exact multiple of 90 degrees, the rotation works somehow even after a move in layoutSubviews.
I understand that my button's transform is being altered in layoutSubviews and this results in the subsequent weirdness when I attempt to rotate it with the above code. I have currently worked around this problem by placing the button I wish to rotate inside another UIView and then moving that view around as desired, but I'd like a better solution that doesn't require redoing my screen layouts.
How can I adjust/alter my button's transform after a move, so that this rotation code continues to work as expected?
The problem you are facing is that a view's frame is "undefined" if it's transform isn't the identity transform.
What you should do is use the view's center property to move it around. That works even if you've changed it's transform.
You can also apply a rotation to the view's layer instead of the view (although be aware that the layer transform is a CATransform3D, a 4x4 transformation matrix instead of a 3x3, so you need different methods to manipulate it.)

Rotate coordinate System of an UIView

Im a complete beginner, so please excuse my maybe stupid question.
Im using an UIView "superview" with many children-images to perform a rotation of the images around an arbitrary point:
superview.transform = CGAffineTransformMakeRotation(M_PI/2);
This works perfect, but it seems like this is rotating the coordinate system of the superview as well. This in turn messes up all following steps. I find hundreds of posts and infos concerning rotating images and for mac development there obviously is a method for rotating coordinate systems. I just don't find anything for iOS.
Is there a way to rotate a view without rotating the coord system / how can I rotate the coord system without influencing the images?
Thanks for any help.
it seems like this is rotating the coordinate system of the superview as well
You're right -- rotating the coordinate system of the superview is exactly what you're doing:
superview.transform = CGAffineTransformMakeRotation(M_PI/2);
Is there a way to rotate a view without rotating the coord system
Sure, just set the transform property for your view rather than for its superview. For any view someView, you can say:
someView.transform = CGAffineTransformMakeRotation(M_PI/2);
Note that this actually rotates the view's own coordinate system -- it doesn't rotate the view itself. That means that all your drawing will be rotated, but the view's frame will remain the same. You might need to adjust the frame to account for this. For example, if you have a rectangular view that's normally 100px high and 300px wide, you might want to make it 300px high and 100px wide to ensure that the content is all still visible.
If you're creating a custom view, you can of course refer to instances of that view from inside its own code using self:
self.transform = CGAffineTransformMakeRotation(M_PI/2);

Rotate Image on Slider Value in iOS

I am rotating the image on slider value -
I am using this code for rotation -
editingView.transform = CGAffineTransformRotate(editingView.transform,sliderVal);
its Rotating properly but if i am trying to move or resize after rotation,The editingView is resizing with unexpected behavior and view disappears from screen.
Please suggest me what i am doing wrong.
Well whenever you rotate a view which is inside a superview, you should preserve the position of the view. If you are not rotating any view across the origin then, you should first translate the view's origin to the superview's origin and then rotate and then again translate back to the original point.
Find the coordinate if the view you want to rotate with respect to its superview, say it (x,y).
Translate the view to the origin as;
view.transform = CGAffineTransformMakeTranslation(x,y)
Rotate the view by some angle, say PI,
view.transform = CGAffineTransformMakeRotation(PI)
After rotation translate back to the original point as;
view.transform = CGAffineTransformMakeTranslation(-x,-y)
And that's it. It should work with all the different rotation.
Have a look at this question.
Since you do not show any code on how you do the move or resizing, I suspect you are not properly concatenating the transforms. Furthermore, after you did the rotation, a translation will possibly work on the rotated coordinate system, therefore leading to unexpected behaviour.
Changing transform value affecting the frame value of UIView. As Apple says:
Warning: If this property is not the identity transform, the value of
the frame property is undefined and therefore should be ignored.
Apple docs
So, if you are moving or resizing your view using frame property, try do this with bounds, center properties

Move a UIImageView after applying CGAffineTransformRotate behave incorrect

I'm trying to rotate UIImageView for certain degrees with CGAffineTransformMakeRotation() function, but it end with imageView only rotates, but when I moved to another coordinates then imageView stretched or change height and width. I have no clue why this happens.
Here is a code:
double a = atan2(dx,dy);
bowImageView.transform = CGAffineTransformMakeRotation(a);
WHen you apply a transform to a view the geometry changes. If you wish to move that view rotated, the simplest solution is to set the transform back to CGAffineTransformIdentity, move the view and reapply the rotation.
The other way is to work out the movement based on the current rotation.....but I find the first solution easier!

Resources