Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS: How to align (left/right) a UIImageView when using UIViewContentModeScaleAspectFill?

I'm playing with the contentMode property of the UIImageView.

When I set it to UIViewContentModeScaleAspectFill, the image is scaled to fit the screen. It's centered. So right and left (or top and bottom, depending on the screen orientation) part of the picture are clipped.

I'd like to have the same behaviour but not centered. Is that possible to have the image to be clipped only on the right (or left) side? (again top or bottom depending on the orientation) ?

thanks

like image 403
Alexis Avatar asked Feb 14 '13 15:02

Alexis


People also ask

What is a UIImageView object?

An object that displays a single image or a sequence of animated images in your interface. Image views let you efficiently draw any image that can be specified using a UIImage object. For example, you can use the UIImageView class to display the contents of many standard image files, such as JPEG and PNG files.

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.

What is UIView contentmode scaletofill?

The UIView.ContentMode.scaleToFill value scales the image without regard to the original aspect ratio, which can cause the image to appear distorted. Other content modes place the image at the appropriate location in the image view’s bounds without scaling it.

What is contentmode in UIImageView in iOS?

Images are an essential component of an app. We use them everywhere, and you might need a different position and size for each place. UIImageView uses its contentMode property to control these behaviors. UIKit offer thirteen different mode for contentMode for us to work with.


2 Answers

I know it's been a while since February, but I just encountered the same need in the app I am developing.

I solved it using a custom UIImageView which can be easily integrated into your existing code (it's a drop-in replacement of UIImageView).

You can find the class on github, along with an example: https://github.com/reydanro/UIImageViewAligned

Hope this helps you on your next projects

like image 144
Andrei Stanescu Avatar answered Nov 15 '22 07:11

Andrei Stanescu


The iOS way to do this is to manipulate the contentsRect of the layer of the UIImageView. Consider the following example (in my custom UIImageView sub class) to align left or right (instead of center which is default):

- (void)updateImageViewContentsRect {
    CGRect imageViewContentsRect = CGRectMake(0, 0, 1, 1);

    if (self.image.size.height > 0 && self.bounds.size.height > 0) {

        CGRect imageViewBounds = self.bounds;
        CGSize imageSize = self.image.size;

        CGFloat imageViewFactor = imageViewBounds.size.width / imageViewBounds.size.height;
        CGFloat imageFactor = imageSize.width / imageSize.height;

        if (self.alignmentMode == AHTImageAlignmentModeLeft) {

            if (imageFactor > imageViewFactor) {
                CGFloat scaledImageWidth = imageViewBounds.size.height * imageFactor;
                CGFloat xOffset = (scaledImageWidth - imageViewBounds.size.width) / 2;
                imageViewContentsRect.origin.x = -(xOffset / scaledImageWidth);
            } else if (imageFactor < imageViewFactor) {
                CGFloat scaledImageHeight = imageViewBounds.size.width / imageFactor;
                CGFloat yOffset = (scaledImageHeight - imageViewBounds.size.height) / 2;
                imageViewContentsRect.origin.y = -(yOffset / scaledImageHeight);
            }

        } else if  (self.alignmentMode == AHTImageAlignmentModeRight) {

            if (imageFactor > imageViewFactor) {
                CGFloat scaledImageWidth = imageViewBounds.size.height * imageFactor;
                CGFloat xOffset = (scaledImageWidth - imageViewBounds.size.width);
                imageViewContentsRect.origin.x = (xOffset / scaledImageWidth) / 2;
            } else if (imageFactor < imageViewFactor) {
                CGFloat scaledImageHeight = imageViewBounds.size.width / imageFactor;
                CGFloat yOffset = (scaledImageHeight - imageViewBounds.size.height);
                imageViewContentsRect.origin.y = (yOffset / scaledImageHeight) / 2;
            }

        }
    }
    self.layer.contentsRect = imageViewContentsRect;
}
like image 29
Werner Altewischer Avatar answered Nov 15 '22 05:11

Werner Altewischer