How do I center a UIImageView within a full-screen UIScrollView?

How do I center a UIImageView within a full-screen UIScrollView?

In my application, I would like to present the user with a full-screen photo viewer much like the one used in the Photos app. This is just for a single photo and as such should be quite simple. I just want the user to be able to view this one photo with the ability to zoom and pan.

I have most of it working. And, if I do not center my UIImageView, everything behaves perfectly. However, I really want the UIImageView to be centered on the screen when the image is sufficiently zoomed out. I do not want it stuck to the top-left corner of the scroll view.

Once I attempt to center this view, my vertical scrollable area appears to be greater than it should be. As such, once I zoom in a little, I am able to scroll about 100 pixels past the top of the image. What am I doing wrong?

@interface MyPhotoViewController : UIViewController <UIScrollViewDelegate> {     UIImage* photo;     UIImageView *imageView; } - (id)initWithPhoto:(UIImage *)aPhoto; @end  @implementation MyPhotoViewController  - (id)initWithPhoto:(UIImage *)aPhoto {     if (self = [super init])     {         photo = [aPhoto retain];          // Some 3.0 SDK code here to ensure this view has a full-screen         // layout.     }      return self; }  - (void)dealloc {     [photo release];     [imageView release];     [super dealloc]; }  - (void)loadView {     // Set the main view of this UIViewController to be a UIScrollView.     UIScrollView *scrollView = [[UIScrollView alloc] init];     [self setView:scrollView];     [scrollView release]; }  - (void)viewDidLoad {     [super viewDidLoad];      // Initialize the scroll view.     CGSize photoSize = [photo size];     UIScrollView *scrollView = (UIScrollView *)[self view];     [scrollView setDelegate:self];     [scrollView setBackgroundColor:[UIColor blackColor]];      // Create the image view. We push the origin to (0, -44) to ensure     // that this view displays behind the navigation bar.     imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, -44.0,         photoSize.width, photoSize.height)];     [imageView setImage:photo];     [scrollView addSubview:imageView];      // Configure zooming.     CGSize screenSize = [[UIScreen mainScreen] bounds].size;     CGFloat widthRatio = screenSize.width / photoSize.width;     CGFloat heightRatio = screenSize.height / photoSize.height;     CGFloat initialZoom = (widthRatio > heightRatio) ? heightRatio : widthRatio;     [scrollView setMaximumZoomScale:3.0];     [scrollView setMinimumZoomScale:initialZoom];     [scrollView setZoomScale:initialZoom];     [scrollView setBouncesZoom:YES];     [scrollView setContentSize:CGSizeMake(photoSize.width * initialZoom,         photoSize.height * initialZoom)];      // Center the photo. Again we push the center point up by 44 pixels     // to account for the translucent navigation bar.     CGPoint scrollCenter = [scrollView center];     [imageView setCenter:CGPointMake(scrollCenter.x,         scrollCenter.y - 44.0)]; }  - (void)viewWillAppear:(BOOL)animated {     [super viewWillAppear:animated];     [[[self navigationController] navigationBar] setBarStyle:UIBarStyleBlackTranslucent];     [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackTranslucent animated:YES]; }  - (void)viewWillDisappear:(BOOL)animated {     [super viewWillDisappear:animated];     [[[self navigationController] navigationBar] setBarStyle:UIBarStyleDefault];     [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES]; }  - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {     return imageView; }  @end 

Function Variable passed to setTimeout not working?


How to define a function that returns an NSString in Objective-C / Iphone SDK
This code should work on most versions of iOS (and has been tested to work on 3.1 upwards)..
Cocoa or Objective-C?
It's based on the Apple WWDC code for PhotoScroller..
Persisting Custom Objects
Add the below to your subclass of UIScrollView, and replace tileContainerView with the view containing your image or tiles:.
Checkbox in iOS application
- (void)layoutSubviews {     [super layoutSubviews];      // center the image as it becomes smaller than the size of the screen     CGSize boundsSize = self.bounds.size;     CGRect frameToCenter = tileContainerView.frame;      // center horizontally     if (frameToCenter.size.width < boundsSize.width)         frameToCenter.origin.x = (boundsSize.width - frameToCenter.size.width) / 2;     else         frameToCenter.origin.x = 0;      // center vertically     if (frameToCenter.size.height < boundsSize.height)         frameToCenter.origin.y = (boundsSize.height - frameToCenter.size.height) / 2;     else         frameToCenter.origin.y = 0;      tileContainerView.frame = frameToCenter; } 

What is the AppDelegate for and how do I know when to use it?

Concatenating NSArray contents with NSMutableString AppendString


Am I using NSUserDefaults wrong?
Have you checked out the UIViewAutoresizing options?. (from the documentation).
UIViewAutoresizing Specifies how a view is automatically resized. 

enum { UIViewAutoresizingNone = 0, UIViewAutoresizingFlexibleLeftMargin = 1 << 0, UIViewAutoresizingFlexibleWidth = 1 << 1, UIViewAutoresizingFlexibleRightMargin = 1 << 2, UIViewAutoresizingFlexibleTopMargin = 1 << 3, UIViewAutoresizingFlexibleHeight = 1 << 4, UIViewAutoresizingFlexibleBottomMargin = 1 << 5 }; typedef NSUInteger UIViewAutoresizing;


Are you using IB to add the scroll view? Change the autosizing options of the scrollview to the attached image.

alt text.


Were you able to solve this problem? I'm stuck with a similar issue.

I think the reason behind it is because the zoomScale applies to the whole contentSize, regardless of the actual size of the subview inside the scrollView (in your case it's an imageView).

The contentSize height seems to be always equal or greater than the height of the scrollView frame, but never smaller.

So when applying a zoom to it, the height of the contentSize gets multiplied by the zoomScale factor as well, that's why you're getting an extra 100-something pixels of vertical scroll..


You probably want to set the bounds of the scroll view = bounds of the image view, and then center the scroll view in its containing view.

If you place a view inside a scroll view at an offset from the top, you will get that empty space above it..

98 out of 100 based on 58 user ratings 758 reviews