Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change UIImageView size to match image with AutoLayout

I want to change my UIImageView height/width to match the image i choose from photo album and i found a snippet on here that does that.

-(CGRect)frameForImage:(UIImage *)imgs inImageViewAspectFit:(UIImageView *)imagev
{
  float imageRatio = imgs.size.width / imgs.size.height;
  float viewRatio = imagev.frame.size.width / imagev.frame.size.height;
  if(imageRatio < viewRatio)
  {
    float scale = imagev.frame.size.height / imgs.size.height;
    float width = scale * imgs.size.width;
    float topLeftX = (imagev.frame.size.width - width) * 0.5;
    NSLog(@"image after aspect fit: width=%f",width);
    imagev.frame = CGRectMake(topLeftX, 0, width, imagev.frame.size.height);
    return CGRectMake(topLeftX, 0, width, imagev.frame.size.height);
  }
  else
  {
    float scale = imagev.frame.size.width / imgs.size.width;
    float height = scale * imgs.size.height;
    float topLeftY = (imagev.frame.size.height - height) * 0.5;
    NSLog(@"image after aspect fit: height=%f", height);
    imagev.frame = CGRectMake(0, topLeftY, imagev.frame.size.width, height);
    return CGRectMake(0, topLeftY, imagev.frame.size.width, height);
  }
}

The problem is that it changes the UIImageView height/width when i call it from a button

- (IBAction)changeSize:(id)sender
{
  [self frameForImage:image inImageViewAspectFit:self.imageView];    
}

But i want it to do that as soon as i choose a image from photo album and this is how i have it set up.

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
  image = [info objectForKey:UIImagePickerControllerOriginalImage];
  [self.imageView setImage:image];
  [self frameForImage:image inImageViewAspectFit:self.imageView];
  [self dismissViewControllerAnimated:YES completion:NULL];
}
like image 201
Mike Tyson Avatar asked Jun 02 '13 00:06

Mike Tyson


People also ask

How do I change the size of my UIImageView?

The simplest way is to set the frame of your UIImageView and set the contentMode to one of the resizing options. I would NOT retain the result here. newImage will be autoreleased already, and it should up to the method that called this to retain it or not.

Does UIImageView have intrinsic content size?

Here is the essential problem: the only way in which UIImageView interacts with Auto Layout is via its intrinsicContentSize property. That property provides the intrinsic size of the image itself, and nothing more.

How do I change aspect ratio in UIImageView?

To maintain aspect ratio I calculated the width of UIImageView = (320/460)*450 = 313.043 dynamically. And set the contentMode For UIImageView is UIViewContentModeScaleAspectFit. And set the image(320x460) to image view but it is some what blur.

What is the difference between a UIImage and a UIImageView?

UIImage contains the data for an image. UIImageView is a custom view meant to display the UIImage .

What is the default value of UIImageView scaleaspectfit?

This is the default value of UIImageView if you initialize it programmatically. scaleAspectFit scales the content to fit within the image view bounds and maintaining the aspect ratio. This might leave an empty space on one axis. This is the default value of UIImageView created in a Storyboard.

How do I control excess portion of an image's view's bounds?

Some content mode can cause an image to excess its view's bounds such as scaleAspectFill, center, and topLeft. You can control whether this excess portion will be clipped to view's bounds or show as is using clipsToBounds property. Setting clipsToBounds to true causes subviews to be clipped to the bounds of the receiver.

What is estimatedheaderheight in UITableView?

UITableView.automaticDimension is what enables AutoLayout to calculate the height of each cell at runtime. estimatedHeaderHeight should be set to a rough estimate of the total height of its content to display the scrolling indicator. These properties can be set in the Size Inspector when selecting the TableView in your storyboard.


2 Answers

Auto Layout solution

Since establishing that you're using Auto Layout in your project, I have made a demo app to show you how you could change the image of the image view and adjust the height. Auto Layout will do this for you automatically, but the catch is that the photo you'll be using is coming from the users gallery and so they're likely to be very big and this.

So check out the app: https://bitbucket.org/danielphillips/auto-layout-imageview

The trick is to create a reference of the NSLayoutConstraint of the height of the image view. When you change your image, you need to adjust it's constant to the correct height given the fixed width.

Your other solution could be to set a contentMode on your image view, by using UIViewContentModeScaleAspectFit your image will always appear in full but will be locked to the bounds of the image view, which can change based on the Auto Layout constraints you have.

Initial reply

It looks like you've really over complicated this, unless I've missed something.

When you get a new image from the image picker, all you need to do is change the frame of the image view according to the UIImage size.

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
  image = [info objectForKey:UIImagePickerControllerOriginalImage];
  [self.imageView setImage:image];
  self.imageView.frame = CGRectMake(self.imageView.frame.origin.x
                                    self.imageView.frame.origin.y
                                    image.size.width
                                    image.size.height);
  [self dismissViewControllerAnimated:YES completion:NULL];
}

Of course this is going to be potentially very large (it's using the original image which may be very large).

So let's lock the width to 280 points... this way we can always have the full image on screen in portrait mode.

So assuming your image size is 1000x800, and our image view perhaps is 280x100. We can calculate the correct height for the image view retaining the image view's width like this:

CGSize imageSize        = CGSizeMake(1000.0, 800.0);
CGSize imageViewSize    = CGSizeMake(280.0, 100.0);

CGFloat correctImageViewHeight = (imageViewSize.width / imageSize.width) * imageSize.height;

self.imageView.frame = CGRectMake(  self.imageView.frame.origin.x,
                                    self.imageView.frame.origin.x,
                                    CGRectGetWidth(self.imageView.bounds),
                                    correctImageViewHeight);
like image 84
Daniel Avatar answered Oct 14 '22 07:10

Daniel


Here is a Swift class that will help return the correct sizing for an image based on a width or height limit that you choose:

class func returnImageSizeForHeightLimit(heightLimit:CGFloat?, orWidthLimit widthLimit:CGFloat?, forImage theImage:UIImage)->CGSize?{

    if let myHeightLimit = heightLimit {

        let theWidth = (myHeightLimit/theImage.size.height) * theImage.size.width

        return CGSizeMake(theWidth, myHeightLimit)
    }

    if let myWidthLimit = widthLimit {

        let theHeight = (myWidthLimit/theImage.size.width) * theImage.size.height

        return CGSizeMake(myWidthLimit, theHeight)
    }

    return nil
}
like image 41
PJeremyMalouf Avatar answered Oct 14 '22 09:10

PJeremyMalouf