5

I have been unable to find the answer for this issue I am having.

I have a UIImageView inside a UIScrollView, and I would like the center its content vertically.

Right now, the only way I have been able to do this is by setting the scroll view's contentInset based on the height of the UIImageView size, but this is not a perfect solution; it just increases the size of the UIImageView, making the UIScrollView 'think' its content is bigger, and adds these black bars to the top.

I've tried to get help from:

UIScrollView with centered UIImageView, like Photos app

and

Center content of UIScrollView when smaller

But have not been able to solve it using those answers.

Community
  • 1
  • 1
runmad
  • 14,846
  • 9
  • 99
  • 140
  • I am also struggling to find a fix for this. It seems there is no simple way to center the content of a scrollView. – Jonah Sep 20 '09 at 14:08

6 Answers6

6

This code should work on most versions of iOS (and has been tested to work on 3.1 upwards, which is all I currently have access to).

It's based on the Apple WWDC code mentioned in Jonah's answer.

Add the below to your subclass of UIScrollView, and replace tileContainerView with the view containing your image or tiles:

- (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;
}
JosephH
  • 37,173
  • 19
  • 130
  • 154
  • I am working on an iPad app and wanted to center the image shown in the DetailView. I didn't subclass UIScrollView, instead added this code to shouldAutorotateToInterfaceOrientation and it now works well in both landscape and portrait modes. Thanks for sharing. – Sushant Jan 19 '11 at 11:13
4

You can tell the UIScrollView to scroll to specific view by calling scrollRectToVisible:animated:

Example:

[myScrollView scrollRectToVisible:imageView.frame animated:YES];

To center it vertically, try this:

1) Add an empty view to your scrollview that is the same height of your contentSize.

2) Add your UIImageView to the center of the emptyView

2) scrollRectToVisible on this empty view.

bentford
  • 33,038
  • 7
  • 61
  • 57
1

Create a separate uiview and add the UIImageView centered in this, then add the view to the scrollview

UIView *view = [[UIVIew alloc] initWithFrame:<frame that will fill your scrollview>];
CGRect frame = CGRectMake((view.size.width - IMAGE_WIDTH)/2, (view.size.height - IMAGE_HEIGHT)/2, IMAGE_WIDTH, IMAGE_HEIGHT);
UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame];
imageView.image = [UIImage imageNamed:@"imageSized_IMAGE_WIDTH_by_IMAGE_HEIGHT.png"];
[view addSubview:imageView];
[imageView release];

[scrollView addSubview:view];
[view release];

Note that you will need to set the view frame to be the dimensions and location you need in the scrollview. The important part to note is the centering of the imageview inside the view frame by using the view frames dimensions as variables.

coneybeare
  • 33,113
  • 21
  • 131
  • 183
  • This will work sort of. The problem is that if the image is smaller than the UIView, it will scroll partially off the screen. The photos app doesn't allow this and it looks much nicer. – Jonah Sep 19 '09 at 20:45
  • 1
    Yeah, I have seen the issue Jonah is talking about in some apps. The ONLY app I have seen that was able to do what we want properly is Apple's Photos.app :( So far, I am just centering my image inside a UIView that's then the image size + whatever insets I need to have it be centered inside the UIScroolView. Not optimal, since it adds black bars in the top and bottom. Looks a bit better if I remove the scrollbars (like Photos.app) – runmad Sep 21 '09 at 18:03
1

Apple has released the 2010 WWDC session videos to all members of the iphone developer program. One of the topics discussed is how they created the photos app!!! They build a very similar app step by step and have made all the code available for free.

It does not use private api either. I can't put any of the code here because of the non disclosure agreement, but here is a link to the sample code download. You will probably need to login to gain access.

http://connect.apple.com/cgi-bin/WebObjects/MemberSite.woa/wa/getSoftware?code=y&source=x&bundleID=20645

And, here is a link to the iTunes WWDC page:

http://insideapple.apple.com/redir/cbx-cgi.do?v=2&la=en&lc=&a=kGSol9sgPHP%2BtlWtLp%2BEP%2FnxnZarjWJglPBZRHd3oDbACudP51JNGS8KlsFgxZto9X%2BTsnqSbeUSWX0doe%2Fzv%2FN5XV55%2FomsyfRgFBysOnIVggO%2Fn2p%2BiweDK%2F%2FmsIXj

Jonah
  • 4,810
  • 14
  • 63
  • 76
0

this can help

myImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth;

http://developer.apple.com/iPhone/library/documentation/UIKit/Reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/instp/UIView/autoresizingMask

basically what you can do with autoresizingMask is that you can control the "anchors" of that view, within its parent view, just as if you were using Interface Builder

Camilo Sanchez
  • 1,528
  • 1
  • 14
  • 18
0

contentInset shouldn't change the contentSize, it should change the contentOffset.

Try setting the contentSize, then the contentInset. Also look into the background color of the UIScrollView and what might be showing behind it. I have no trouble centering a UIImageView in a UIScrollView using setContentSize, setContentInset and addSubview.

David Kanarek
  • 12,611
  • 5
  • 45
  • 62