Ios: Add Imageview in a Scrollview to Have Zoom

IOS: add imageview in a scrollview to have zoom

  1. Set your view controller up as a <UIScrollViewDelegate>
  2. Draw your UIScrollView the size you want for the rectangle at the center of the view. Set the max zoom in the inspector to something bigger than 1. Like 4 or 10.
  3. Right click on the scroll view and connect the delegate to your view controller.
  4. Draw your UIImageView in the UIScrollView and set it up with whatever image you want. Make it the same size as the UIScrollView.
  5. Ctrl + drag form you UIImageView to the .h of your View controller to create an IBOutlet for the UIImageView, call it something clever like imageView.
  6. Add this code:

    -(UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView
    {
    return self.imageView;
    }
  7. Run the app and pinch and pan til your heart's content.

UIImageView and UIScrollView zooming

All you need to do is add your UIImageView (or any view you want to zoom) inside your UIScrollView.

Set your maximumZoomScale on your UIScrollView to any value higher than 1.0f.

Set yourself as the delegate of your UIScrollView and return the UIImageView in the viewForZooming delegate method.

That's it. No pinch gesture needed, no nothing. UIScrollView handles pinch zooming for you.

Using a scroll view to zoom in an image with Swift

Let us begin with the constraints, your scrollview was added correctly,
now for your imageView, drag and drop it inside your scrollview, specify the left right top and bottom constraints the way you want and center your imageView vertically and horizontally just like the screenshots below

left right top bottom constraints

center imageView

Let us proceed with the imageView.

Select it on your storyboard and in the assistant editor change the content mode to aspect fit like so :

aspect fit

Now lets move to the code,

by typing scrollView.delegate = ViewController() you are creating a new instance of type ViewController and you're not using your existing one this is why you should replace this line with :

scrollView.delegate = self

This way you will be referring to your superclass which is your existing view controller

and consider adding this too:

scrollView.minimumZoomScale = 1.0
scrollView.maximumZoomScale = 5.0

scrollView.contentSize = .init(width: 2000, height: 2000)

Best,
Marc

How to zoom a UIImageView within a UIScrollView?

You have to implement the following delegate method for zooming:

-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}

and make sure that you add self.imageView to your self.scrollView instead.
It should look like this:

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

CGSize scrollableSize = CGSizeMake(self.view.frame.size.width, self.view.frame.size.height);
[self.scrollView setContentSize:scrollableSize];

self.imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"test.png"] ];
self.imageView.frame = CGRectMake(0, 0, self.scrollView.frame.size.width, self.view.frame.size.height);

self.scrollView.backgroundColor = [UIColor blackColor];
self.scrollView.minimumZoomScale = 1.0 ;
self.scrollView.maximumZoomScale = self.imageView.image.size.width / self.scrollView.frame.size.width;
self.scrollView.delegate = self;

[self.scrollView addSubview:self.imageView];
}

UIImageView in UIScrollView does not zoom correctly

Since you don't want the image to zoom, I recommend you don't even bother with the zoom controls. A UIImageView knows how to scale its content.

I recommend you do it like this:

  1. Add a constraint that sets the imageView height equal to the scrollView height. This will prevent vertical scrolling.
  2. Add a constraint that sets the imageView width equal to the imageView height with multiplier image.size.width / image.size.height.
  3. Set imageView content mode to .scaleToFill.

To allow you to change the image, keep an aspectRatio property that retains the aspect ratio constraint set in step 2. Set aspectRatio.isActive = false, and then create and activate a new constraint for the new image.

Also, if you might ever have images that aren't wide enough to fill the scrollView horizontally when scaled to fit vertically, consider these changes:

  1. Replace the constraint that sets the imageView width with one that sets the width equal to the imageView height with multiplier max(image.size.width / image.size.height, scrollView.bounds.width / scrollView.bounds.height).
  2. Set imageView content mode to .scaleAspectFit.

Then, when you have a narrow image, the imageView will fill the scrollView, but the .scaleAspectFit will show the entire image centered in the scrollView. This will still work correctly for wide images because the multiplier will match the image aspect ratio and .scaleAspectFit will fill the entire imageView.

Use a scrollview to zoom an image in Xcode 11 avoiding the Ambiguous Content Size AutoLayout error

Interface Builder / Storyboard has no way of knowing that you will be adding subview(s) and constraints at run-time.

So, it is telling you that your current layout has an Ambiguous Content Size.

Would it be better to not show the message if the scroll view has no content? Maybe... but even though it is showing a design error, that doesn't mean you must fix it.

If you really want to get rid of the warning/error, couple options:

1) Add your imageView (with proper constraints) in Storyboard, and set the .image property at run-time.

2) Add a subview (with proper constraints) in Storyboard, and remove that view in viewdidLoad() before adding the imageView.


Edit

Here's a simple example: https://github.com/DonMag/ZoomTest

In IB / Storyboard, I added a UIScrollView and set only the width, height, centerX and centerY constraints, so Storyboard tells me Ambiguous Content Size.

In viewDidLoad, I add a UIImageView, set proper constraints, set scroll view delegate and min/max zoom scale.


Edit 2

Results using a 256 x 256 image, and constraining the scroll view to fill the parent view (scroll view background is cyan)...

On load - zoomScale == 1:

Sample Image

On load - zoomScale == 1 - rotated:

Sample Image

zoomScale = approximately 1.5 (just wide enough to fit):

Sample Image

zoomScale = approximately 1.5 - after rotation:

Sample Image

zoomScale == 5 - panned to top-left:

Sample Image

zoomScale == 5 - panned to top-left - after rotation:

Sample Image

zoomScale == 5 - panned to lower-right:

Sample Image

zoomScale == 5 - panned to lower-right - after rotation:

Sample Image



Related Topics



Leave a reply



Submit