Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIScrollView zooming with Auto Layout

I'm trying to implement a UIScrollView the New Way, using Auto Layout. I've set up constraints from the inner view to the scroll view so that it can compute its own contentSize automatically, and that works like a charm— except that all hell breaks loose when I try to zoom in or out. I can't even properly describe what happens, other than to say that the inner view gets "messed up".

You can see an example of this behavior here (not my project; you have to set the scroll view's maximumZoomScale and implement -viewForZoomingInScrollView: before zooming will work).

Has anyone else run into this behavior? Is there currently any way to get zooming in a UIScrollView to work with Auto Layout without essentially re-implementing the zooming behavior yourself?

like image 323
phu Avatar asked Dec 25 '12 00:12

phu


People also ask

What is Ui scroll view?

UIScrollView is the superclass of several UIKit classes, including UITableView and UITextView . A scroll view is a view with an origin that's adjustable over the content view. It clips the content to its frame, which generally (but not necessarily) coincides with that of the app's main window.


2 Answers

The best answer that I have seen is Mark's (https://stackoverflow.com/users/1051919/mark-kryzhanouski), posted here: UIScrollView Zoom Does Not Work With Autolayout.

The crux of it is that you have to anchor the image view that is nested in the scroll view, to the parent of the scroll view. Despite the guidance in the iOS 6 release notes, it is not intuitive to me what view is "floating" over what. In this case, the scrolling view is just a single image view.

I did do a lot of experimentation with this, hoping to find an all-IB approach and found none. You can still generate the view hierarchy in IB, but you still have to programatically add constraints. You can delete some or all of the default constraints (mainly just to appease the constraint-conflict warnings), but you always need Mark's code to tie the image view to the parent of the scroll view, the grand-parent of the image view.

It seems like it should be simpler than this - it "should just work" but:

NSDictionary *viewsDictionary = @{ @"scrollView": self.scrollView, @"imageView": self.imageView }; [self.view addConstraints:[NSLayoutConstraint     constraintsWithVisualFormat:@"H:|[imageView(width)]"     options:0     metrics:@{@"width": @(self.imageView.image.size.width)}     views:viewsDictionary]];  [self.view addConstraints:[NSLayoutConstraint     constraintsWithVisualFormat:@"V:|[imageView(height)]"     options:0     metrics:@{@"height": @(self.imageView.image.size.height)}     views:viewsDictionary]]; 
like image 57
Chris Conover Avatar answered Oct 06 '22 15:10

Chris Conover


Without adding an imageView in the storyboard, I've found the following works perfectly:

-(UIImageView *)imageView {     if (!_imageView) _imageView = [[UIImageView alloc] initWithFrame:CGRectZero];     return _imageView; } - (void)viewDidLoad {     [super viewDidLoad];     [self.scrollView addSubview:self.imageView];     // Set the min and max:     self.scrollView.minimumZoomScale = 0.2;     self.scrollView.maximumZoomScale = 5.0;     self.scrollView.delegate = self;      // Set the content:     self.scrollView.zoomScale = 1.0; // reset zoomScale for new image     self.scrollView.contentSize = CGSizeMake(image.size.width/2, image.size.height/2);     self.imageView.frame = CGRectMake(0, 0, image.size.width/2, image.size.height/2);     self.imageView.image = image; }  -(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {     return self.imageView; } 
like image 22
AMayes Avatar answered Oct 06 '22 16:10

AMayes