UIScrollView zoom is not working properly - ios

Whenever I click on an image, I want the image to display as a larger image with the ability to zoom. So far when I click on the image, it displays as I want it to inside a scrollview. However, I have to get lucky to be able to zoom in properly. Most of the time when I attempt to zoom, the image just moves down and to the right and does not zoom at all. Here is my code:
-(void) pictureButtonAction
{
self.scrollImageView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
self.scrollImageView.contentSize = self.fullImageView.image.size;
self.scrollImageView.delegate = self;
self.scrollImageView.clipsToBounds = YES;
self.scrollImageView.scrollEnabled = YES;
[self.scrollImageView setMaximumZoomScale:4.0f];
[self.scrollImageView setMinimumZoomScale:1.0f];
[self.view addSubview:self.scrollImageView];
[self.scrollImageView addSubview:fullImageView];
}
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView
{
return self.fullImageView;
}

ImageViews frame got changed while zooming , so that it moves down. So, You have to centralize the image view each time you zoom .
your scrollviews contentsize should be greater than or equal to your image size , if your fullImageView.image.size is less than your scrollviews bounds ,then set your scrollviews contentSize atleast double the scrollviews bounds .
call the below function in scrollViewDidZoom delegate method
-(void) centerScrollViewContents
{
CGSize boundsSize = self.scrollView.bounds.size;
CGRect contentsFrame = self.imageView.frame;
if (contentsFrame.size.width < boundsSize.width) {
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0f;
} else {
contentsFrame.origin.x = 0.0f;
}
if (contentsFrame.size.height < boundsSize.height) {
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0f;
} else {
contentsFrame.origin.y = 0.0f;
}
self.imageView.frame = contentsFrame;
}
Try this , hope it will help you ; happy coding ! :)

#Maria's answer works but when zooming you'll experience unwanted bounces, instead of using it under scrollViewDidZoom, use scrollViewDidEndZooming: delegate to prevent that..
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
[self centerScrollViewContents];
}
and with a little enhancement from her code:
[UIView animateWithDuration:0 animations:^{
self.previewImageView.frame = contentsFrame;
}];
a bit late for an answer but i hope this will be useful to some..

Related

UIView inside a Scrollview zooming issue

I have a photo displaying iOS application in which the user should be able to view and zoom the image. As per the requirement the image should be displayed in entire scree(no transparent portion should be displayed and the image should fill the entire screen) and hence myself used AspectFill mode for UIImageView. In order to implement zooming functionality, used a UIScrollView and implemented viewForZoomingInScrollView delegate method of UIScrollView. The image view is connected to four edges of scroll view in StoryBoard and two constraints (imageHeight and imageWidth) are connected to IBOutlet. These constraints will be updated in ViewControllers viewDidLayoutSubviews method.
I have added the code below for your reference.
- (void)setImageViewModes {
self.scrollView.minimumZoomScale = CALCULATD_ZOOM_SCALE;
self.pageImageView.contentMode = UIViewContentModeScaleAspectFill;
}
pragma mark - UIScrollView Delegate
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return MY_IMAGE_VIEW;
}
- (void)updateImageViewConstraints {
self.imageHeight.constant = CGRectGetHeight(self.scrollView.frame);
self.imageWidth.constant = CGRectGetWidth(self.scrollView.frame);
[self.view layoutIfNeeded];
}
However when I try to zoom out the image, it is rebounding to its initial state and outer portion of the image is clipped(It display only the initial filled portion of image). Is there is any workaround available to see the entire image on zoom out ?
I tried by setting minimum zoom scale for UIScrollView(I have a method in my code to calculate the minimum zoom scale of image) and the zoom functionality works. However when we zoom out, the UIIMage is always moves to top left corner of scrollview(Attached the screen shot for your reference).
I found a solution for this issue by Center content of UIScrollView when smaller (third answer) by subclassing UIScrollView and adjust image view frame in ‘layoutSubviews’ method of scroll view. This works fine while zoom out. But when we zoom and scroll the image to see the edge/side portion, scrollview readjust the image view to centre and I am unable to see the side portion of image in zoom in state. Any workaround for this issue ?
Use This
-(void)scrollViewDidZoom:(UIScrollView *)scrollView1{
[self centerScrollViewContent];
}
- (void)centerScrollViewContent {
CGSize boundsSize = self.scrollView.bounds.size;
CGRect contentsFrame = self.drawingView.frame;
if (contentsFrame.size.width < boundsSize.width) {
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0f;
} else {
contentsFrame.origin.x = 0.0f;
}
if (contentsFrame.size.height < boundsSize.height) {
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0f;
} else {
contentsFrame.origin.y = 0.0f;
}
self.drawingView.frame = contentsFrame;
}
Swift 3 version of Rahul's code
func scrollViewDidZoom(_ scrollView: UIScrollView) {
centerContentView()
}
func centerContentView() {
let boundsSize = scrollView.bounds.size
var contentFrame = contentView.frame
if contentFrame.size.width < boundsSize.width {
contentFrame.origin.x = (boundsSize.width - contentFrame.size.width) / 2.0
} else {
contentFrame.origin.x = 0.0
}
if contentFrame.size.height < boundsSize.height {
contentFrame.origin.y = (boundsSize.height - contentFrame.size.height) / 2.0
} else {
contentFrame.origin.y = 0.0
}
contentView.frame = contentFrame
}

Objective C - Cannot zoom UIImageView that is embedded into UIScrollView

I'm a new kid on the block here. Nice to meet you all.
I'm trying to implement Ray Wenderlich's zooming of an UIScrollView that was described here:
http://www.raywenderlich.com/10518/how-to-use-uiscrollview-to-scroll-and-zoom-content
But it seemed like it didn't work for me. What I would like to do is:
Create the UIImageView from a nib.
Add UIImageView to the UIScrollView.
Zoom it in from the center of the image with the scale of 2 at the start of the view if the app is executed from an iPad.
Here's my code:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//Hide the status bar
[[UIApplication sharedApplication] setStatusBarHidden:YES];
//------------------------------
//Initialize the image view of the home screen
_mapView = (TM_MapView *)[[[NSBundle mainBundle]loadNibNamed:#"MapView" owner:self options:nil]objectAtIndex:0];
// set the content size to be the size our our whole frame
mapScrollView.contentSize = _mapView.imageView.image.size;
[mapScrollView setScrollEnabled:YES];
//set the selector for the buttons in the map view
[self setButtonsSelector];
// now add our scroll view to the main view
[mapScrollView addSubview:_mapView];
//------------------------------
NSLog(#"_mapView.imageView.frame: %#", NSStringFromCGRect( _mapView.imageView.frame));
NSLog(#"_mapView.imageView.image.size: %#", NSStringFromCGSize( _mapView.imageView.image.size));
NSLog(#"mapScrollView.contentSize: %#", NSStringFromCGSize( mapScrollView.contentSize));
}
-(void)viewWillAppear:(BOOL)animated
{
mapScrollView.minimumZoomScale = 1.0f;
mapScrollView.maximumZoomScale = 2.5f;
mapScrollView.zoomScale = 1.0f;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
[self zoomOnStart];
}
}
-(void)zoomOnStart
{
NSLog(#"Zooming on start");
CGPoint zoomPoint = CGPointMake(512.0f, 384.0f);
CGFloat newZoomScale = 2.0f;
CGSize scrollViewSize = self.mapScrollView.bounds.size;
CGFloat w = scrollViewSize.width / newZoomScale;
CGFloat h = scrollViewSize.height / newZoomScale;
CGFloat x = zoomPoint.x - (w/2.0f);
CGFloat y = zoomPoint.y - (h/2.0f);
CGRect rectToZoomTo = CGRectMake(x, y, w, h);
//CGRect rectToZoomTo = CGRectMake(300, 300, 200, 100);
NSLog(#"rectToZoomTo: %#", NSStringFromCGRect(rectToZoomTo));
[self.mapScrollView zoomToRect:rectToZoomTo animated:YES];
}
#pragma mark - Delegates
-(UIView*)viewForZoomingInScrollView:(UIScrollView*)scrollView
{
NSLog(#"Scroll View viewForZoomingInScrollView");
return _mapView;
}
-(void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
NSLog(#"Scroll View End Zooming!");
}
-(void)scrollViewDidZoom:(UIScrollView *)scrollView
{
NSLog(#"Scroll View Zoom changed to: %f", scrollView.zoomScale);
}
As you can see, I've logged some of the frames and delegates to see the input for the zooming and to see whether or not we are zooming. Here's the console logs:
2014-10-09 17:24:18.507 TrueMuzeiOS[13268:60b] _mapView.imageView.frame: {{0, 0}, {1024, 768}}
2014-10-09 17:24:18.511 TrueMuzeiOS[13268:60b] _mapView.imageView.image.size: {1024, 768}
2014-10-09 17:24:18.513 TrueMuzeiOS[13268:60b] mapScrollView.contentSize: {1024, 768}
2014-10-09 17:24:18.519 TrueMuzeiOS[13268:60b] Zooming on start
2014-10-09 17:24:18.521 TrueMuzeiOS[13268:60b] rectToZoomTo: {{320, 128}, {384, 512}}
As you can see, the logs inside viewForZoomingInScrollView:, scrollViewDidEndZooming:withView:atScale:, and scrollViewDidZoom: didn't get called, meaning we are not zooming at all (CMIIW). I've added the UIScrollViewDelegate so it should've worked.
So, can you guys help me here? I've followed the steps correctly, IMHO. So I'm lost now. Thanks a lot in advance.
do you set the delegate property of the UIScrollView?
I don´t see this on the code you published although you could have done it on Interface Builder.
If this the case, simply this would make your methods get called:
mapScrollView.delegate = self;
Check the UIScrollView documentation on the delegate property section to more information.
https://developer.apple.com/library/ios/documentation/uikit/reference/uiscrollview_class/index.html#//apple_ref/occ/instp/UIScrollView/delegate

Issue while zooming uiscrollview which is used to resize and crop Image in IOS

I'm developing an App which has (image saving) in one of the views, I have three different sizes which I want my images to be saved in after the user zoom and scale the image which is captured from the scroll view when the user click on save.
Below is my Codes:
After the style is selected the width and height is set depending on type chosen and then the scrollview creating method called
-(void)viewDidAppear:(BOOL)animated{
if(!([getColor length] == 0))
{
[theColored setHidden:NO];
[imageView setImage:image];
[theStyle setHidden:NO];
[theStyled setHidden:YES];
}
if(!([getStyle length] == 0))
{
[theColored setHidden:NO];
[imageView setImage:image];
[theStyle setHidden:YES];
[theStyled setHidden:NO];
[Save setHidden:NO];
if([theType isEqual: #"Pant"]){
theW = 200;
theH = 260;
}else if ([theType isEqual:#"Shirt"])
{
theW = 220;
theH = 220;
}else if([theType isEqual:#"Shoes"])
{
theW = 200;
theH = 60;
}
// UIImage *savedImage = image;
CGFloat theScale = 1.0;
[self setTheView:image andFrameW:&theW andFrameH:&theH andTheScale:&theScale];
}}
Below is the method:
-(void)setTheView:(UIImage *)savedImage andFrameW:(CGFloat *)theFW andFrameH:(CGFloat *)theFH andTheScale:(CGFloat *)theScale{
NSLog(#"called");
CGFloat theS = *theScale;
CGFloat imgW ;
CGFloat imgH;
imgW = *theFW * theS;
imgH = *theFH * theS;
// = savedImage.size.height * theS;
[dot removeFromSuperview];
[scrollView setPagingEnabled:NO];
[scrollView setShowsHorizontalScrollIndicator:NO];
[scrollView setShowsVerticalScrollIndicator:NO];
scrollView.layer.masksToBounds=YES;
scrollView.minimumZoomScale = 0.1f;
scrollView.maximumZoomScale = 5.0f;
[scrollView setZoomScale:0.5];
scrollView.layer.borderColor = [UIColor blackColor].CGColor;
scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0);
[scrollView setContentSize:CGSizeMake(imgW*2,imgH*2)];
dot =[[UIImageView alloc] initWithFrame:CGRectMake(imgW/2,imgH/2,imgW,imgH)];
dot.image=savedImage;
dot.contentMode = UIViewContentModeScaleAspectFit;
[scrollView setScrollEnabled:YES];
[scrollView setTranslatesAutoresizingMaskIntoConstraints:YES];
scrollView.frame = CGRectMake(scrollView.frame.origin.x,scrollView.frame.origin.y, *theFW , *theFH);
[scrollView setHidden:NO];
[scrollView setContentOffset:CGPointMake(imgW/2,imgH/2) animated:NO];
[scrollView addSubview:dot];
}
Zooming methods:
- (UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView {
return dot;
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale{
NSLog(#"zoomed");
NSLog(#"%f",scale);
[self setTheView:image andFrameW:&theW andFrameH:&theH andTheScale:&scale];
}
Problem:
I have two problems here:
1- The zoom scale is not starting from last point it reached.
2- While tapping to zoom moves even before start zooming.
Update Edit
Both problems Solved
instead of calling the method again after zooming i just changed the content size
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale{
[self setTheView:image andFrameW:&theW andFrameH:&theH andTheScale:&scale];
}
replaced with
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale{
scrollView.contentSize = CGSizeMake((dot.bounds.size.width*scale)*2,(dot.bounds.size.height*scale)*2);
}
But i have new problem came up, after zooming contentOffSet is not equal up and down and also left and write
Digram explanation:
<----------------------------Content Size---------------------------->
| left offset |<---------Scrollviewframe--------->|Right offset|
i tried to set new content offset:
[scrollView setContentOffset:CGPointMake((dot.bounds.size.width*scale)/2,(dot.bounds.size.height*scale)/2) animated:NO];
but made nothing..
Problem solved i wanted to share the answer if someone wants to use scrollview to crop and zoom while allowsEditing = YES; doesn't gives the ability to set the rect size
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale{
CGFloat zoomedW = dot.bounds.size.width*scale;
CGFloat zoomedH = dot.bounds.size.height*scale;
CGFloat frameW = scrollView.frame.size.width;
CGFloat frameH = scrollView.frame.size.height;
scrollView.contentSize = CGSizeMake(frameW+zoomedW ,frameH+zoomedH);
}

UIKit Dynamics: Attachment inside UITableViewCell

My table view cells contain a circle in an UIView, indicating a value. I want to add the UIKit Dynamics attachment behaviour to that circle in order to for it to lag a bit when scrolling.
I don't want to attach the individual cells to each other but only the circle view to the UITableViewCell. The rest of the cell should scroll as usual.
Problem: The UITableViewCell has its origin always at (0, 0). How can I add the circle to a view that actually does move when scrolling?
I finally got it to work. The UITableView moves the coordinate system of every cell and of all views contained within that cell. Therefor I needed to manually move my view inside the UITableViewCell during scrolling while still referring to the initial anchor point.
The table view controller:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
BOOL scrollingUp = '\0';
if (self.lastContentOffset > scrollView.contentOffset.y) {
scrollingUp = YES;
}
else if (self.lastContentOffset < scrollView.contentOffset.y) {
scrollingUp = NO;
}
NSInteger offset = 64; // To compensate for the navigation bar.
if (scrollingUp) {
offset = offset - scrollView.contentOffset.y;
}
else {
offset = offset + scrollView.contentOffset.y;
}
// Limit the offset so the views will not disappear during fast scrolling.
if (offset > 10) {
offset = 10;
}
else if (offset < -10) {
offset = -10;
}
// lastContentOffset is an instance variable.
self.lastContentOffset = scrollView.contentOffset.y;
for (UITableViewCell *cell in self.tableView.visibleCells) {
// Use CoreAnimation to prohibit flicker.
[UIView beginAnimations:#"Display notification" context:nil];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationBeginsFromCurrentState:YES];
cell.view.frame = CGRectMake(cell.view.frame.origin.x, offset, cell.view.frame.size.width, cell.view.frame.size.height);
[UIView commitAnimations];
[cell.dynamicAnimator updateItemUsingCurrentState:cell.view];
}
}
The table view cell:
-(void)layoutSubviews {
[super layoutSubviews];
// _view is the animated UIView.
UIDynamicItemBehavior *viewBehavior = [[UIDynamicItemBehavior alloc] initWithItems:#[_view]];
viewBehavior.elasticity = 0.9f;
UIAttachmentBehavior *attachmentBehaviorView = [[UIAttachmentBehavior alloc] initWithItem:_view attachedToAnchor:CGPointMake(_anchorView.frame.origin.x + _anchorView.frame.size.width / 2.0f, _anchorView.frame.origin.y + _anchorView.frame.size.height / 2.0f)];
attachmentBehaviorView.damping = 8.0f;
attachmentBehaviorView.frequency = 4.0f;
attachmentBehaviorView.length = 0.0f;
[_dynamicAnimator addBehavior:viewBehavior];
[_dynamicAnimator addBehavior:attachmentBehaviorView];
}
You can change the anchorPoint of UIAttachmentBehavior during -[scrollViewDidScroll:]. You may refer to the following code snippet:
- (void)viewDidLoad
{
UIDynamicAnimator *animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];
UIAttachmentBehavior *behavior1 = [[UIAttachmentBehavior alloc] initWithItem:self.circleView
attachedToAnchor:[self tableViewAnchor]];
behavior1.length = 10.0;
behavior1.damping = 0.3;
behavior1.frequency = 2.5;
[animator addBehavior:behavior1];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
behavior1.anchorPoint = [self.tableView convertPoint:[self tableViewAnchor] toView:self.view];
}
- (CGPoint)tableViewAnchor
{
return CGPointMake(160.0, 154.0); // return your target coordination w.r.t. the table view
}
Preview:

content jumps on zooming out with UIScrollView

I want help with my UIScrollView sample.
I created a simple program that scrolls and zooms the content (UIImageView). It works fine, except that the content frequently disappears to the right-bottom when I try zooming out. But since I set minimumZoomScale to 1.0f, it is actually not zooming out, only the content is jumping out of the view. And what is even more weird is that I cannot scroll up after this. Apparently content size is messed up as well.
The setup I have in my sample code is as in the figure below.
When I checked the status after (trying) zooming out, I found two wrong things.
_scrollView.contentSize is 480x360, which should not be smaller than 1000x1000
_scrollView.bounds jumped to the top somehow (i.e., _scrollView.bounds.origin.y is always 0)
To cope with the two items above, I added following code in my UIScrollViewDelegate and now it works fine.
- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view
{
if(scrollView == _scrollView && view == _contentView)
{
// Setting ivars for scrollViewDidZoom
_contentOffsetBeforeZoom = _scrollView.contentOffset;
_scrollViewBoundsBeforeZoom = _scrollView.bounds;
}
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
if(scrollView == _scrollView)
{
// If you zoom out, there are cases where ScrollView content size becomes smaller than original,
// even though minimum zoom scale = 1. In that case, it will mess with the contentOffset as well.
if(_scrollView.contentSize.width < CONTENT_WIDTH || _scrollView.contentSize.height < CONTENT_HEIGHT)
{
_scrollView.contentSize = CGSizeMake(CONTENT_WIDTH, CONTENT_HEIGHT);
_scrollView.contentOffset = _contentOffsetBeforeZoom;
}
// If you zoom out, there are cases where ScrollView bounds goes outsize of contentSize rectangle.
if(_scrollView.bounds.origin.x + _scrollView.bounds.size.width > _scrollView.contentSize.width ||
_scrollView.bounds.origin.y + _scrollView.bounds.size.height > _scrollView.contentSize.height)
{
_scrollView.bounds = _scrollViewBoundsBeforeZoom;
}
}
}
However, does it need to come down to this? This is a very simple sequence, and it is hard to believe that Apple requires us to put this kind of effort. So, my bet is I am missing something here...
Following is my original code. Please help me find what I am doing wrong (or missing something)!
#define CONTENT_WIDTH 1000
#define CONTENT_HEIGHT 1000
>>>> Snip >>>>
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
_scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
_scrollView.contentSize = CGSizeMake(CONTENT_WIDTH, CONTENT_HEIGHT);
_scrollView.backgroundColor = [UIColor blueColor];
_scrollView.maximumZoomScale = 8.0f;
_scrollView.minimumZoomScale = 1.0f;
_scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
_scrollView.scrollEnabled = YES;
_scrollView.delegate = self;
[self.view addSubview:_scrollView];
_contentView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"sample.jpg"]]; // sample.jpg is 480x360
CGPoint center = (CGPoint){_scrollView.contentSize.width / 2, _scrollView.contentSize.height / 2};
_contentView.center = center;
[_scrollView addSubview:_contentView];
_scrollView.contentOffset = (CGPoint) {center.x - _scrollView.bounds.size.width / 2, center.y - _scrollView.bounds.size.height / 2};
}
- (UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView
{
if(scrollView == _scrollView)
{
return _contentView;
}
return nil;
}
I created a quick sample project and had the same issue you described using the code you pasted. I don't exactly know what the "proper" way to zoom is in iOS but I found this tutorial which says that you need to recenter your contentView after the scrollView has been zoomed. I would personally expect it to be automatically re-centered given that it is the view you're returning in the viewForZoomingInScrollView delegate method but apparently not.
- (void)centerScrollViewContents {
CGSize boundsSize = _scrollView.bounds.size;
CGRect contentsFrame = _contentView.frame;
if (contentsFrame.size.width < boundsSize.width) {
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0f;
} else {
contentsFrame.origin.x = 0.0f;
}
if (contentsFrame.size.height < boundsSize.height) {
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0f;
} else {
contentsFrame.origin.y = 0.0f;
}
_contentView.frame = contentsFrame;
}
- (void)scrollViewDidZoom:(UIScrollView *)scrollView {
// The scroll view has zoomed, so we need to re-center the contents
[self centerScrollViewContents];
}
The code above is not written by me but is simply copied from the tutorial. I think its pretty straightforward. Also, centring the contentView seems to be a lot more elegant then constantly changing the bounds and content size of the scrollview so give it a try.
If anyone is having an issue of bouncing when you zooming out resulting background to show, try removing bounces (Bounces Zoom) in Interface Builder.
I was able to fix this problem using the delegate answer that adjusted the rates after zoom... but then I remembered I was using auto-layout, and just adding constraints for centering horizontally and vertically (in addition to the constraints tying the image to each edge of the scroll view) solved the issue for me without using the delegate methods.
Olshansk answer in swift 5
func scrollViewDidZoom(_ scrollView: UIScrollView) {
centerScrollViewContents()
}
func centerScrollViewContents() {
let boundsSize = scrollView.bounds.size;
var contentsFrame = container.frame;
if (contentsFrame.size.width < boundsSize.width) {
contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width) / 2.0;
} else {
contentsFrame.origin.x = 0.0;
}
if (contentsFrame.size.height < boundsSize.height) {
contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height) / 2.0;
} else {
contentsFrame.origin.y = 0.0;
}
container.frame = contentsFrame;
}

Resources