Why does the UIImageView change after resizing?

I am new to using transforms. And still disagree with how they work.

What I'm trying to do is rotate my UIImageView with a given angle. But after rotation, it changes the size of the image, becomes smaller. I also do scaling for ImageView, so it will not be flipped. How to rotate and save the size that was set in CGRectMake when ImageView was selected?

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]; 

Thanks a lot!

+6
source share
2 answers

Ok, I promised that I would look, so here is my answer:

I am creating a scene that should be somewhat equivalent to yours, the code is as follows:

 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]); 

This code assumes you are using ARC. If not add

 [imageView release]; 

in the end.

Using this code, the logs look like this:

 [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}} 

As you can see, the boundaries always remain the same. What actually changes due to rotation is a frame, because an image that has been rotated 30 Β° C is, of course, wider than if it had not rotated. And since the center point is set to the actual center of the view, the origin of the frame also changes (moves to the left and top). Please note that the size of the image itself does not change . I did not use scale conversion, as the result can be achieved without scaling.

But in order to be clearer, here are some photos for you (0 Β°, 30 Β° rotation 90 Β°): 0 Β°, 30 Β° and 90 Β° rotations of UIImageView

They already look pretty similar, right? I drew the actual frames to make it clear what the difference is between the borders and the frame. The following really makes it clear. I overlaid all the images by rotating them to the negative degrees that the UIImageView rotated, giving the following result: UIImageViews overlayed to show that size doesn't change

So you see a pretty straightforward way to rotate images. Now to your problem, that you really want the frame to remain the same. If you want the final frame to be the size of your original frame (in this example, width 200 and height 250), you will have to scale the resulting frame. But this, of course, will scale the image you don't want. I really think that a larger frame will not be a problem for you - you just need to know that you have to consider this because of the rotation.

In short: it is not possible to have a UIImageView that will have the same frame after rotation. This is not possible for any UIView. Just think of a rectangle. If you rotate it, it will not be a rectangle after the rotation, right?

Of course, you can put your UIImageView in another UIView, which will have a non-rotating frame with a width of 200 and a height of 250, but it will be just superficial, as this will not actually change the fact that the rotated rectangle has a different width and height than the original.

Hope this helps. :)

+15
source

Do not set the contentMode, which UIImageView inherits from UIView, and leads to changes in the frame in accordance with the scaling, transformation, rotation of the device in accordance with the UIViewContentMode you have chosen.

Also, if you just want to rotate, you can just change the frame using: -

 [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]; } 

If you do not want the animation to change the frame

Try using this: -

 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
source

Source: https://habr.com/ru/post/915595/


All Articles