Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIScrollView Zoom Does Not Work With Autolayout

Zooming with UIScrollView using a strictly autolayout environment does not seem to work.

This is especially frustrating because the iOS 6 release notes certainly lead me to believe it should when the wrote about a "Pure Auto Layout approach" here http://developer.apple.com/library/ios/#releasenotes/General/RN-iOSSDK-6_0/_index.html

I looked the the WWDC 2012 slides for sessions 202, 228, and 232 and didn't see an answer for this.

The only question I've seen on the internet specifically for this issue is UIScrollView zooming with Auto Layout, but it doesn't provide code of the problem and there is no answer.

This user https://stackoverflow.com/users/341994/matt has given many great responses to UIScrollView autolayout questions and even linked to code on git hub, but I haven't been able to find anything that answers this issue there.

I have attempted to boil this issue down to the absolute minimum to make it clear.

I created a new single view application with a storyboard, and made no changes in the interface builder.

I added a large picture file to the project "pic.jpg".

SVFViewController.h

#import <UIKit/UIKit.h>  @interface SVFViewController : UIViewController <UIScrollViewDelegate> @property (nonatomic) UIImageView *imageViewPointer; @end 

SVFViewController.m

#import "SVFViewController.h"  @interface SVFViewController ()  @end  @implementation SVFViewController   - (void)viewDidLoad {     [super viewDidLoad];     // Do any additional setup after loading the view, typically from a nib.      UIScrollView *scrollView = [[UIScrollView alloc] init];     UIImageView *imageView = [[UIImageView alloc] init];     [imageView setImage:[UIImage imageNamed:@"pic.jpg"]];     [self.view addSubview:scrollView];     [scrollView addSubview:imageView];      scrollView.translatesAutoresizingMaskIntoConstraints = NO;     imageView.translatesAutoresizingMaskIntoConstraints = NO;     self.imageViewPointer = imageView;     scrollView.maximumZoomScale = 2;     scrollView.minimumZoomScale = .5;     scrollView.delegate = self;      NSDictionary *viewsDictionary = NSDictionaryOfVariableBindings(scrollView,imageView);     NSLog(@"Current views dictionary: %@", viewsDictionary);     [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|" options:0 metrics: 0 views:viewsDictionary]];     [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|" options:0 metrics: 0 views:viewsDictionary]];     [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[imageView]|" options:0 metrics: 0 views:viewsDictionary]];     [scrollView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[imageView]|" options:0 metrics: 0 views:viewsDictionary]]; }  -(UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView{     return self.imageViewPointer; }  @end 

Notice I made a particular effort to make this as much like the sample code provided in the iOS 6 release notes, just doing the bare minimum to implement zooming.

So, the problem?

When you run this application and pan around in the scroll view, everything is good. But when you zoom the problem is obvious, the image flickers back and forth, and the placement of the image within the scroll view gets more wrong with every zoom.

It looks like there is battle going on for the content offset of the imageView, it seems it is being set to different values by two different things with every "zoom". (an NSLog of the content offset property of the imageView appears to confirm this).

What am I doing wrong here? Does anyone know how to property implement zooming within a UIScrollView in an purely autolayout environment. Is there an example of this anywhere out there?

Please help.

like image 291
Corey Avatar asked Jan 21 '13 06:01

Corey


People also ask

How to make a view controller scrollable?

One way to do this is programmatically create an UIScrollView in your UIViewController . To control the scrollability you can set the ScrollView contentSize property.

How does UIScrollView work?

Overview. 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.


1 Answers

Once again, re-reading the iOS SDK 6.0 release notes I found that:

Note that you can make a subview of the scroll view appear to float (not scroll) over the other scrolling content by creating constraints between the view and a view outside the scroll view’s subtree, such as the scroll view’s superview.

Solution

Connect your subview to the outer view. In another words, to the view in which scrollview is embedded.

And applying constraints in following way I've got it work:

[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|" options:0 metrics: 0 views:viewsDictionary]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|" options:0 metrics: 0 views:viewsDictionary]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[imageView(width)]" options:0 metrics:@{@"width":@(self.imageViewPointer.image.size.width)} views:viewsDictionary]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[imageView(height)]" options:0 metrics:@{@"height":@(self.imageViewPointer.image.size.height)} views:viewsDictionary]]; 
like image 68
Mark Kryzhanouski Avatar answered Oct 14 '22 12:10

Mark Kryzhanouski