Configuring UIScrollView Zoom Scaling to Fit the Screen

My task is to copy the behavior of many applications that use photos, where UIScrollView displayed with UIImageView inside, it corresponds to the image by the size of the screen, even if this image is smaller.

I am sure that this should not be done with a UIImageView frame, but controlled using a UIScrollView , but how ...?


In my code, I have a method called updateZoom that calculates the minimumZoomScale value and also assigns this value to the zoomScale property. I guess this is the right place to calculate math and calculate zoomScale manually.

This is the method:

 - (void)updateZoom { float minZoom = MIN(self.view.bounds.size.width / self.imageView.image.size.width, self.view.bounds.size.height / self.imageView.image.size.height); if (minZoom > 1) { minZoom = 1; } self.scrollView.minimumZoomScale = minZoom; self.scrollView.zoomScale = minZoom; } 

I hope someone gives me a hit on how to set zoomScale according to UIScrollView limitations.

+7
ios objective-c iphone uiscrollview uiimageview
source share
5 answers

The solutions above work, but I tried to understand why. I would like to share these two articles, which I found extremely useful when setting up mininumZoomScale correctly and using this to work with iOS8 / Xcode 6.

First, in order to get a scroll view for working in iOS8, you need to set the correct limits from the start. Other posters recommended, and I agree that there should only be one view of the content in your scroll view. It’s great to embed all of your other views into one content view, but you don’t want to set scroll view restrictions on a bunch of small views.

Combine the top, leading, trailing, and lower limits with the scroll view from the content view (in my case, it is a UIImageView) with a constant of 0. This sets the edges of your scroll view of the content view.

Then set the size of the content view using restrictions of equal width and equal height for the scroll view. You cannot use fixed width and fixed height in the content view, as scaling will not work, and you will not be able to control the size yourself. Without these restrictions, iOS8 sets the size to (0,0) before you get a chance leading to some odd artifacts. With these restrictions, call the updateZoom method in the orientation method, and you are kind. In iOS7, call it in didRotateFromInterfaceOrientation. In iOS8, call it from viewWillTransitionToSize. You will need to update the code for the new size.

Many thanks to Natasha Robot for solving the restriction: http://natashatherobot.com/ios-autolayout-scrollview/

When you call your updateZoom method to set your minimum, you should also check if the current current zoom is <your minimumZoomScale and reset, if so. You should not reset zoomScale otherwise, as this will become another suspicious look of your user when changing orientation.

As for the rest and why the math works, Joe Conway in objc.io put it all in this fantastic border-frame article using UIScrollViews: http://www.objc.io/issue-3/scroll-view.html

Thanks to both and the poster above.

 -(void)updateZoom { self.scrollView.minimumZoomScale = MIN(self.scrollView.bounds.size.width / self.imageView.image.size.width, self.scrollView.bounds.size.height / self.imageView.image.size.height); if (self.scrollView.zoomScale < self.scrollView.minimumZoomScale) self.scrollView.zoomScale = self.scrollView.minimumZoomScale; } 
+10
source share

The solution was quite simple ... Check this code (modified version of the method from OP):

 - (void)updateZoom { float zoomScale = MIN(self.view.bounds.size.width / self.imageView.image.size.width, self.view.bounds.size.height / self.imageView.image.size.height); if (zoomScale > 1) { self.scrollView.minimumZoomScale = 1; } self.scrollView.minimumZoomScale = zoomScale; self.scrollView.zoomScale = zoomScale; } 

I think there is nothing to explain, because the code is straightforward.

+5
source share

To set the scale that matches the size of the image in scrollView, set the minimum Zoom for scrollView using this: self.scrollView.minimumZoomScale = self.scrollView.frame.size.width/ self.imageView.frame.size.width;

Above the code will match your image in scrollView Width.

+2
source share

SWIFT 3

Thanks to @chewy, this worked for me (I needed to add “frames” to the image):

 func setZoomScale() { var minZoom = min(self.view.bounds.size.width / imageView!.bounds.size.width, self.view.bounds.size.height / imageView!.bounds.size.height); if (minZoom > 1.0) { minZoom = 1.0; } scrollView.minimumZoomScale = minZoom; scrollView.zoomScale = minZoom; } 

Then call setZoomScale () in "override func viewWillLayoutSubviews ()"

+1
source share

And here is the Swift 3 version

 var minZoom = min(self.view.bounds.size.width / theImage!.size.width, self.view.bounds.size.height / theImage!.size.height); if (minZoom > 1.0) { minZoom = 1.0; } self.scrollImg.minimumZoomScale = minZoom; self.scrollImg.zoomScale = minZoom; 
0
source share

All Articles