Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Zooming UIImageView inside UIScrollView with autolayout

I have a UIImageView embedded inside a UIScrollView, prior to iOS 6 and autolayout I used the following snippet inside the controller's viedDidLoad method to display a scrollable and zoomable image.

self.scrollView.contentSize = self.imageView.image.size;
self.imageView.frame = CGRectMake(0, 0, self.imageView.image.size.width, self.imageView.image.size.height);

But now the constraints set in the storyboard are used instead. I've found this question Embed ImageView in ScrollView with Auto Layout on iOS 6 and some others here in SO stating that constraints are loaded/enforced after viewDidLoad, and that moving my previous snippet to viewDidAppear would fix this issue but zooming does not work properly and it seems that the sizes of the scrollView and the imageView are reset to the storyboard's constraint after a pinch-to-zoom gesture.

I'm just guessing, but I think maybe if there's some way to override the scrollView's and imageView's vertical and horizontal space constraints in code that might work.

Anyone else having this issues?

like image 824
Diego Allen Avatar asked Jan 23 '13 02:01

Diego Allen


2 Answers

The best solution was proposed by Zsolt in the comments:

http://github.com/evgenyneu/ios-imagescroll check this out. Works perfectly for me.

The solution proposed in this repository is to adjust the minimum and current zoom level before displaying the image:

@interface MyViewController () <UIScrollViewDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end


@implementation MyViewController

- (void)viewDidLoad
{
  [super viewDidLoad];
  self.scrollView.delegate = self;

  [self initZoom];
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
  [self initZoom];
}

// Zoom to show as much image as possible
- (void) initZoom {
  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) return;

  self.scrollView.minimumZoomScale = minZoom;

  self.scrollView.zoomScale = minZoom;
}

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

However sample conatins issue with zooming out. Image is not getting centered. This can be easily fixed by using the custom scroll view class with the following code in it:

@interface MyScrollView : UIScrollView
@end

@implementation MyScrollView

-(void)layoutSubviews
{
  [super layoutSubviews];
  UIView* v = [self.delegate viewForZoomingInScrollView:self];
  CGFloat svw = self.bounds.size.width;
  CGFloat svh = self.bounds.size.height;
  CGFloat vw = v.frame.size.width;
  CGFloat vh = v.frame.size.height;
  CGRect f = v.frame;
  if (vw < svw)
    f.origin.x = (svw - vw) / 2.0;
  else
    f.origin.x = 0;
  if (vh < svh)
    f.origin.y = (svh - vh) / 2.0;
  else
    f.origin.y = 0;
  v.frame = f;
}

@end
like image 81
Anton Matosov Avatar answered Nov 12 '22 05:11

Anton Matosov


Solved my problem using the following code sample. The github repository corresponds to the book Programming iOS by Matt Neuburg.

https://github.com/mattneub/Programming-iOS-Book-Examples/blob/11c6c57743b04e6e722b635b87be69fa41a5abaf/ch20p573scrollViewAutoLayout/ch20p573scrollViewAutoLayout/ViewController.m

like image 7
Diego Allen Avatar answered Nov 12 '22 07:11

Diego Allen