I am making a simple app for the iPad that consists of a giant image that you can zoom-in/out on and navigate.
This image is placed inside a UIImageView
, which is then placed inside a UIScrollView
.
The navigation and zooming work 100% fine; however, the image is loaded at a fixed aspect-ratio to fit the screen, and will never change (even when zooming-in).
I have a feeling that Interface Builder is setting some property that I'm not aware of, but I've tried everything that I can think of to fix this.
The Problem:
When the app initially loads, the contents inside the UIScrollView
is automatically re-sized to exactly fit the iPad screen by having its aspect ratio changed./fixed; the actual image is giant (way bigger than the iPad resolution). This scaled aspect ratio remains even when zooming in on the image, and causes the image to look stretched.
No matter what I try, I cannot stop the iPad from automatically rescaling my image. I simply want the app to start with my image displayed normally (100% zoom) on the iPad, with the portion that currently fits on the iPad screen being the top-left corner of the image.
What I've tried to fix it:
I tried changing the UIImageView's
content-mode in Interface Builder to "Top-Left". This appeared to work perfectly, but then I realized that the UIScrollView
would not let you scroll around the image past the initially displayed portion (the top-left). You could zoom-in on the top-left portion and scroll, but never past what was initially shown on the screen.
Code:
Here's the code that I'm using to setup the views. imageScrollView
is the UIScrollView
, and imageView
is the UIImageView
. They are both IBOutlets
.
// Set the needed attributes of the imageView
[imageView setImage:[UIImage imageNamed: @"TestImage.png"]];
imageView.userInteractionEnabled = YES;
// Set a bunch of the imageScrollView attributes.
// calculate minimum scale to perfectly fit image width, and begin at that scale
float minimumScale = [imageScrollView frame].size.width / [imageView frame].size.width;
[imageScrollView setMinimumZoomScale:minimumScale];
[imageScrollView setZoomScale:1];
[imageScrollView setMaximumZoomScale:10];
[imageScrollView setContentSize:CGSizeMake(imageView.frame.size.width, imageView.frame.size.height)];
[imageScrollView setScrollEnabled:YES];
[imageScrollView setUserInteractionEnabled:YES];
imageScrollView.clipsToBounds = YES;
imageScrollView.bounces = FALSE;
imageScrollView.bouncesZoom = FALSE;
I also have two UIGestureRecongizers
to handle tap-zooming, but I do not believe that they are the issue. When I comment them out, nothing changes.
Any help would be extremely appreciated.
I fixed it!
For anyone else having the same problem, here's how I fixed the code:
The Cause of the bug was that Interface Builder was forcing the views to use the ScaleToFill
contentMode
. Setting the ScrollView's
contentMode to UIViewContentModeScaleAspectFit
didn't work on its own, since the imageView
was still being distorted.
The Fix:
The following code had to be added at the end of the setup for the UIScrollView
and UIImageView
(inside of the viewDidLoad()
method):
[imageScrollView setContentMode:UIViewContentModeScaleAspectFit];
[imageView sizeToFit];
[imageScrollView setContentSize:CGSizeMake(imageView.frame.size.width, imageView.frame.size.height)];
Explanation:
First, the UIScrollView's
contentMode
is set to AspectFit
, like @Mike suggested. Then, sizeToFit() is called on the imageView
to override Interface Builder's annoying presets, and to make the image the correct size.
The last line is important. You must set the contentSize
for the ScrollView AFTER you re-size the imageView
. Otherwise, the ScrollView
will think that the image is still the size of the iPad display, and therefore won't think that there's anything to scroll. Setting the size of the ScrollView
after resizing the ImageView
and changing the ScrollView's
contentMode
makes the ScrollView
the actual size of the image.
Hope that helped!
Thanks for the help Mike, it got me on the right track :)
Since the imageView
is the content of the scrollview, try changing the ScrollView's
content mode to UIViewContentModeScaleAspectFit
. Try calling setNeedsDisplay
on the imageview
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With