I want to set a transform of a view as another view. For example I have UIImageView and I want to have the same transform in another UIImageView like in the first one.
I try to make it by using CGAffineTransformMakeRotation, but I don't know how to get the relative angle of the first UIImageView, to make the rotation. Maybe it can be done in different way?
I made a picture to explain the effect which I want to get:
Best regards,
EDIT: I want to set second one in the same position like the first one. Not in the same place, but with the same angle for example to the border of screen.
It's simply just need to assign the transform of one view to other.
eg.
self.imageView1.transform = CGAffineTransformMakeRotation( 45.0/180*M_PI );
self.imageView2.transform = self.imageView1.transform;
imageView2 will same transform as ImageView1.
okay, u can get the transform of your second image view (20) marked image use that transform to set 4th image view (in your pic) for example,
CGAffineTransform currentTransform = self.imageView_2.transform; //say image view rotated transform
self.imageView_4.transform = currentTransform; //last image set its transform to any view that u want to rotate
Edit:2
i am not get what u want exactly, if u want to place it somewhere, first set the frame and after that apply transform, like
self.imageView_3.frame = self.imageView_1.frame; //set the place where u want to place,
CGAffineTransform currentTransform = self.imageView_2.transform;
self.imageView_3.transform = currentTransform;
edit 3
if u want to rotate back to normal then use like below
self.imageView_3.frame = self.imageView_1.frame; //set the place where u want to place,
CGAffineTransform currentTransform = self.imageView_2.transform;
self.imageView_3.transform = CGAffineTransformIdentity;//currentTransform; //brings back to original
//set the position where u want to place
Here using property transform and method CGAffineTransformMakeRotation of imageView can do that.
e.g.
self.imageView.transform = CGAffineTransformMakeRotation( rotation degree in decimal /180*M_PI);
use animation block to animate accordingly.
[UIView animateWithDuration:1.0 animations:^{
self.imageView.transform = CGAffineTransformMakeRotation( 180.0/180*M_PI);
} completion:^(BOOL finished){
}];
Edit:
In order to rotate imageView same as a another one you can do this by assign transform property of rotated imageView see code below.
self.imageView2.transform = self.imageView1.transform;
Related
I am building a custom UIView that you can rotate and resize. I can resize the UIView by dragging the corners of the UIView. I calculate how much I have dragged then change the frame of the UIView accordingly.
However, I am running into problems once I added a rotation gesture recognizer to the view. If I rotate or apply a transform to the view, I no longer know how to calculate drag distance and change the frame of the view. How could I calculate the width and height change between my new view and the original view when things are put at an added angle or if they have some other transform, like a translation transform?
I thought of possibilities to set the view's transform back to .identity, change the size of the view, then re-apply its transform, but I'm not sure how to actually go about implementing this.
After applying transform you can not use frame
You have two options
1) First Calculate everything using center of your view
2) As you know apply identity and change frame
for point 2 I have added example that might helpful to you
let transform = imageView.transform
imageView.transform = CGAffineTransform.identity
var rect: CGRect = imageView.frame
rect = // Change Rect here
imageView.frame = rect // Assign it
imageView.transform = transform // Apply Transform
I have rotated a UIImageView by calling
myView.transform = CGAffineTransformMakeRotation(someRadians)
myView.layer.allowsEdgeAntialiasing = YES;
If I call...
[myView setFrame:CGRectMake(myView.frame.origin.x, myView.frame.origin.y-100, myView.frame.size.width, myView.frame.size.height)];
... my view gets stretched, rather then simply moving upward a bit.
Is this normal behaviour? Im I not supposed to set the frame after rotating a view? Is there a solution? Thanks.
From the UIView documentation:
Warning: If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.
In other words, don't use a view's frame if it doesn't have the identity transform.
Turns out, as #Scott Berrevoets suggested, there is no way to use the frame property after making a transformation.
Instead we have to move the view with another transformation. In order to not make the move transformation override the rotation, we can concat the translation transformation to the view's existing rotation transformation.
CGAffineTransform moveTransform = CGAffineTransformMakeTranslation(0, -100);
myView.transform = CGAffineTransformConcat(myView.transform, moveTransform);
I have the following super simple animation, I'm basically rotating a view 2 radians from its original angle/center, it rotates fine my only misunderstanding is why does the view move from its original position when the rotation occurs.
[UIView animateWithDuration:1.0 animations:^{
self.someView.transform = CGAffineTransformMakeRotation( 2 );
}];
Why does the view moves when rotated with the code above?
I'm currently trying to discern the information in the CGAffineTransform Reference.
Understanding the anchor point.
I found this threads but it doesn't show a concrete answer.
Why rotating imageView, it changes position?
Thanks a lot
You need to set the anchor point of your view to rotate around.
self.somview.layer.anchorPoint = CGPointMake(0.5, 0.5);
Then start the rotation.
From Apple documentations
#property(nonatomic) CGAffineTransform transform Changes to this
property can be animated. Use the beginAnimations:context: class
method to begin and the commitAnimations class method to end an
animation block. The default is whatever the center value is (or
anchor point if changed)
Link: https://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CALayer_class/Introduction/Introduction.html#//apple_ref/occ/instp/CALayer/anchorPoint
image from here http://www.raywenderlich.com/9864/how-to-create-a-rotating-wheel-control-with-uikit
- As you see the anchor point is the point with the value from 0.0 - 1.0 for X and Y
when you rotate the rotation will be around these points
NOTE: you need to import QuartzCore
I am adding another answer due to #fs_tigre request. The problem is with the auto layouts in your xib file, unfortunately is it unknown why that affects the transform.
Now here is the steps I did to solve the issue:
1- first you need to get rid off your auto layout (yes, you have to)
uncheck Use Autolayout
2- remove all constraints and autoresizing masks for your view that will be rotated, as in the screenshot
(Here I have my blue box, see on the right autoresizing, nothing is selected)
I have made some changes for your rotation's code
self.someView.layer.anchorPoint = CGPointMake(0.5, 0.5);
// one degree = pi/180. so...
// rotate by 90
CGFloat radians = (M_PI/180) * 90;
[UIView animateWithDuration:1.0 animations:^{
self.someView.transform = CGAffineTransformRotate(self.someView.transform, radians);
}];
Click rotate and see the magic :)
The "anchor" of CGAffineTransformMakeRotation is the X,Y of the view. You can try this:
CGPoint center = self.someView.center;
[UIView animateWithDuration:1.0 animations:^{
self.someView.transform = CGAffineTransformMakeRotation( 2 );
self.someView.center = center;
}];
I have set the scale of my stepper as follows :
m_stepper1.transform = CGAffineTransformMakeScale(0.6, 0.6);
After that if I try to rotate vertically, it doesn't make any effect on the stepper. It doesn't get rotated. I used the following code for rotation:
m_stepper1.transform = CGAffineTransformMakeRotation(M_PI / 2.0);
Please some one help me out with this.
You don't need an extra view to accomplish this, all you need is a concat transform. The way you're doing this resets the previous transform before adding the new one. This will add both.
[stepper setTransform:CGAffineTransformConcat(CGAffineTransformMakeRotation(M_PI_2), CGAffineTransformMakeScale(0.6, 0.6))];
If however, you'd like to make the transforms one at a time, you should use one of the transforms that takes an input transform as a parameter. This will also produce the result you're looking for.
[stepper setTransform:CGAffineTransformMakeRotation(M_PI_2)];
[stepper setTransform:CGAffineTransformScale(stepper.transform, 0.6, 0.6)];
You put the UIStepper on a UIView, and rotate UIView.
【edit】
The answer is my fault. Im sorry.
And correct answer is below.
The methods CGAffineTransformMake~ and CGAffineTransform~ have differences.
CGAffineTransformMake~ use for transform FIRST TIME.
If you want to overlap transform, you should use CGAffineTransform~.
This is an example.
CGAffineTransform scale = CGAffineTransformMakeScale(0.6f, 0.6f);
stepper.transform = CGAffineTransformRotate(scale, M_PI / 2.0f);
Please try this.
I'm working on a drawing app.
I want the user to be able to "drop" a shape on the screen and then move, resize or rotate it as desired.
The problem is with the rotation. I have the moving and resizing working fine.
I did this before with a rather complex and memory/processor-intensive process, which I am now trying to improve.
I've searched and searched but haven't found an answer similar to what I'm trying to do.
Basically, let's say the user drops a square on the "surface". Then, they tap it and get some handles. They can touch anywhere and pan to move the square around (working already), touch and drag on a resize handle to resize the square (working already), or grab the rotation handle to have the square rotate around its center.
I've looked into drawing the square using UIBezierPath or just having it be a subclass of UIView that I fill.
In either case, I'm trying to rotate the UIView itself, not some contents inside. Every time I try to rotate the view, either nothing happens, the view vacates the screen or it rotates just a little bit and stops.
Here's some of the code I've tried (this doesn't work, and I've tried a lot of different approaches to this):
- (void) rotateByAngle:(CGFloat)angle
{
CGPoint cntr = [self center];
CGAffineTransform move = CGAffineTransformMakeTranslation(-1 * cntr.x, -1 * cntr.y);
[[self path] applyTransform:move];
CGAffineTransform rotate = CGAffineTransformMakeRotation(angle * M_PI / 180.0);
[[self path] applyTransform:rotate];
[self setNeedsDisplay];
CGAffineTransform moveback = CGAffineTransformMakeTranslation(cntr.x, cntr.y);
[[self path] applyTransform:moveback];
}
In case it isn't obvious, the thinking here it to move the view to the origin (0,0), rotate around that point and then move it back.
In case you're wondering, "angle" is calculated correctly. I've also wrapped the code above in a [UIView beginAnimations:nil context:NULL]/[UIView commitAnimations] block.
Is it possible to rotate a UIView a "custom" amount? I've seen/done it before where I animate a control to spin, but in those examples, the control always ended up "square" (i.e., it rotated 1 or more full circles and came back to its starting orientation).
Is it possible to perform this rotation "real-time" in response to UITouches? Do I need to draw the square as an item in the layer of the UIView and rotate the layer instead?
Just so you know, what I had working before was a shape drawn by a set of lines or UIBezierPaths. I would apply a CGAffineTransform to the data and then call the drawRect: method, which would re-draw the object inside of a custom UIView. This UIView would host quite a number of these items, all of which would need to be re-drawn anytime one of them needed it.
So, I'm trying to make the app more performant by creating a bunch of UIView subclasses, which will only get a command to re-draw when the user does something with them. Apple's Keynote for the iPad seems to accomplish this using UIGestureRecognizers, since you have to use two fingers to rotate an added shape. Is this the way to go?
Thoughts?
Thanks!
-(void)rotate{
CGAffineTransform transform;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationCurve:UIViewAnimationOptionBeginFromCurrentState];
myView.alpha = 1;
transform = CGAffineTransformRotate(myView.transform,0.5*M_PI);
[myView setUserInteractionEnabled:YES];
myView.transform = transform;
[UIView commitAnimations];
}
This might help.
for just simple rotation you might leave out the Animation:
-(void)rotate:(CGFloat)angle
{
CGAffineTransform transform = CGAffineTransformRotate( myView.transform, angle * M_PI / 180.0 );
myView.transform = transform;
}
I use a simple NSTimer to control a animation.