14

I am programmatically setting up an imageview with a border. I set the content mode of the imageView to Aspect Fit, which works, but the border remains the original square.

Code:

CGRect imageViewRect = CGRectMake(left, top, 158, 119); 
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:imageViewRect];
        [imageView setContentMode:UIViewContentModeScaleAspectFit];
        [imageView setImage:image];
        [imageView.layer setBorderColor:[[UIColor blackColor] CGColor]];
        [imageView.layer setBorderWidth:3.0];

Obviously, I want the black border to adjust with the aspect fit and surround the image on all sides. Instead it remains in the original frame, and looks like this:

wHAT IT LOOKS LIKE

jvnbt
  • 2,465
  • 4
  • 20
  • 23

3 Answers3

19

Using a method slightly modified from Frank Schmitt in this post, you can add a method to work out the frame needed to display the image scaled to aspect:

- (CGRect)getFrameSizeForImage:(UIImage *)image inImageView:(UIImageView *)imageView {

    float hfactor = image.size.width / imageView.frame.size.width;
    float vfactor = image.size.height / imageView.frame.size.height;

    float factor = fmax(hfactor, vfactor);

    // Divide the size by the greater of the vertical or horizontal shrinkage factor
    float newWidth = image.size.width / factor;
    float newHeight = image.size.height / factor;

    // Then figure out if you need to offset it to center vertically or horizontally
    float leftOffset = (imageView.frame.size.width - newWidth) / 2;
    float topOffset = (imageView.frame.size.height - newHeight) / 2;

    return CGRectMake(leftOffset, topOffset, newWidth, newHeight);
}

You can then call this after setting your UIImageView image:

CGRect frame = [self getFrameSizeForImage:imageView.image inImageView:imageView]; 

Finally, set the UIImageView's frame using this frame, offsetting position for any change in width/height:

CGRect imageViewFrame = CGRectMake(imageView.frame.origin.x + frame.origin.x, imageView.frame.origin.y + frame.origin.y, frame.size.width, frame.size.height);
imageView.frame = imageViewFrame;
Community
  • 1
  • 1
Ian L
  • 5,553
  • 1
  • 22
  • 37
3

The fastest way I got that done:

  • in IB I set up two imageViews, the top one for my image, and one under it for the border, that I can either just set with a solid color, or use any kind of graphic asset

Then in the code, I adjust the background image frame to be slightly larger than the foreground image:

float kBorderSize=5.0;
CGRect imageRect=AVMakeRectWithAspectRatioInsideRect(imageView.image.size,imageView.frame);
CGRect borderRect=CGRectMake(imageRect.origin.x-kBorderSize, imageRect.origin.y-kBorderSize, imageRect.size.width+2*kBorderSize, imageRect.size.height+2*kBorderSize);
backgroundImage.frame=borderRect;

it requires an import:

#import <AVFoundation/AVUtilities.h>
JP Hribovsek
  • 6,707
  • 2
  • 21
  • 26
0

That border is on the imageView, not on the image. To fix this, you can either resize your UIImageView to be the same size as the image (or have the same width/height ratio as the image if you're scaling down) or actually add a border to the image itself.

Both of these scenarios are covered in this SO question

Community
  • 1
  • 1
MishieMoo
  • 6,620
  • 2
  • 25
  • 35