Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

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
like image 677
Sebastian Celis Avatar asked Apr 27 '09 16:04

Sebastian Celis


People also ask

How do I change aspect ratio in UIImageView?

To maintain aspect ratio I calculated the width of UIImageView = (320/460)*450 = 313.043 dynamically. And set the contentMode For UIImageView is UIViewContentModeScaleAspectFit. And set the image(320x460) to image view but it is some what blur.

What is scroll view in Swift?

The scroll view displays its content within the scrollable content region. As the user performs platform-appropriate scroll gestures, the scroll view adjusts what portion of the underlying content is visible. ScrollView can scroll horizontally, vertically, or both, but does not provide zooming functionality.


1 Answers

This code should work on most versions of iOS (and has been tested to work on 3.1 upwards).

It's based on the Apple WWDC code for PhotoScroller.

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;
}
like image 108
JosephH Avatar answered Oct 31 '22 17:10

JosephH