Search code examples
iosuiscrollviewautolayoutresolutionnslayoutconstraint

Layout constraint to resize image to screen width maintaining aspect ratio


I have a background image which is to be the same width as the iPhone screen but longer in length. I want to scroll the image along the y axis.

I have set up a scroll view and placed an image inside which works fine as I can scroll to view it. Problem is the image is huge - both vertically and horizontally. I want the image to fit the width of the screen and not exceed.

I created the image in Photoshop using the 6 plus dimensions (1242*2208 @ 72ppi) template - with the idea that the aspect ratio is 16:9 for iPhone 5 onwards so all I have to do is set up a constraint to keep the aspect ratio and another to set the width equal to scroll view width. This has had no effect and I'm not sure how to proceed.

This gives me a scroll view that fills the screen (correct!) but an image that is huge inside of it and I need to scroll in both axis. I want the image to resize to fit the scrollview/screen width whilst maintaining it's aspect ratio so the user only needs to scroll up/down.

edit I have adjusted the code to correct the width constraint and add a content mode for the image. It has not resolved

    self.background = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"newOrderBack_stg1.png"]];
self.scrollView.contentSize = self.background.bounds.size;
[self.scrollView addSubview:self.background];

NSLayoutConstraint *constraint = [NSLayoutConstraint
                                 constraintWithItem:self.background
                                 attribute:NSLayoutAttributeHeight
                                 relatedBy:NSLayoutRelationEqual
                                 toItem:self.background
                                 attribute:NSLayoutAttributeWidth
                                 multiplier:16.0/9.0
                                 constant:0.0f];
[self.background addConstraint:constraint];

NSLayoutConstraint *widthConstraint = [NSLayoutConstraint
                                       constraintWithItem:self.background
                                       attribute:NSLayoutAttributeWidth
                                       relatedBy:NSLayoutRelationEqual
                                       toItem:self.scrollView
                                       attribute:NSLayoutAttributeWidth
                                       multiplier:1
                                       constant:0];
[self.scrollView addConstraint:widthConstraint];

self.background.contentMode = UIViewContentModeScaleAspectFill;

It has not worked either


Solution

  • setup your scrollview (without the imageview in it) in storyboard and set its delegate to your viewcontroller. then implement your viewcontroller like this:

    @interface ViewController () <UIScrollViewDelegate>
    
    @property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
    @property (strong, nonatomic) UIImageView *imageView;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"example_image"]];
        self.imageView.translatesAutoresizingMaskIntoConstraints = NO;
    
        [self.scrollView addSubview:self.imageView];
        [self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[imageView]|" options:0 metrics:nil views:@{@"imageView": self.imageView}]];
        [self.scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[imageView]|" options:0 metrics:nil views:@{@"imageView": self.imageView}]];
    }
    
    - (void)viewDidLayoutSubviews {
        CGFloat zoomScale = CGRectGetWidth(self.scrollView.frame) / self.imageView.image.size.width;
    
        self.scrollView.minimumZoomScale = zoomScale;
        self.scrollView.maximumZoomScale = zoomScale;
        self.scrollView.zoomScale = zoomScale;
    }
    
    - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
        return self.imageView;
    }
    
    @end
    

    hope it helps!