Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Borders don't adjust to Aspect Fit?

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

like image 989
user1023127 Avatar asked Mar 14 '12 17:03

user1023127


2 Answers

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;
like image 78
Ian L Avatar answered Oct 30 '22 04:10

Ian L


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>
like image 27
JP Hribovsek Avatar answered Oct 30 '22 04:10

JP Hribovsek