IOS: add imageview in a scrollview to have zoom
- Set your view controller up as a
<UIScrollViewDelegate>
- 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. - Right click on the scroll view and connect the delegate to your view controller.
- Draw your
UIImageView
in theUIScrollView
and set it up with whatever image you want. Make it the same size as theUIScrollView
. - Ctrl + drag form you
UIImageView
to the.h
of your View controller to create anIBOutlet
for theUIImageView
, call it something clever likeimageView
. Add this code:
-(UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.imageView;
}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
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 :
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:
- Add a constraint that sets the imageView height equal to the scrollView height. This will prevent vertical scrolling.
- Add a constraint that sets the imageView width equal to the imageView height with multiplier
image.size.width / image.size.height
. - 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:
- 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)
. - 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:
On load - zoomScale == 1 - rotated:
zoomScale = approximately 1.5 (just wide enough to fit):
zoomScale = approximately 1.5 - after rotation:
zoomScale == 5 - panned to top-left:
zoomScale == 5 - panned to top-left - after rotation:
zoomScale == 5 - panned to lower-right:
zoomScale == 5 - panned to lower-right - after rotation:
Related Topics
Uniquely Identifying an iOS User
In Swiftui, How to Use Uihostingcontroller Inside an Uiview or as an Uiview
Add Glowing Effect to an Skspritenode
Using Uipageviewcontroller with Swift and Multiple View Controllers
Fatal Error: Malformed or Corrupted Ast File - Xcode
Xcode 4: Creating a Uiview Xib, Not Properly Connecting
What Is a Monospace Font in iOS
iOS 9 Uitableview Separators Insets (Significant Left Margin)
iOS Push Notification Banner Shown Twice for a Single Push
How to Get HTML Source from Url with Swift
iOS 11 Navigationitem.Titleview Width Not Set
iOS 11 Large-Title Navigation Bar Not Collapsing
Import Swift Class in Objective-C, <Mymodule>-Swift.H File Not Found
Can't Connect Iboutlet in Interface Builder