如何在全屏UIScrollView中居中UIImageView?

时间:2009-04-27 16:34:50

标签: objective-c iphone uiscrollview uiimageview fullscreen

在我的应用程序中,我想向用户展示一个全屏照片查看器,就像照片应用程序中使用的那样。这仅适用于单张照片,因此应该非常简单。我只是希望用户能够通过缩放和平移来查看这张照片。

我的大部分都在工作。而且,如果我不将UIImageView作为中心,那么一切都表现得非常完美。但是,当图像被充分缩小时,我真的希望UIImageView在屏幕上居中。我不希望它粘在滚动视图的左上角。

一旦我尝试将此视图居中,我的垂直可滚动区域似乎比它应该更大。因此,一旦我放大一点,我就能够滚动大约100像素超过图像的顶部。我做错了什么?

@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

5 个答案:

答案 0 :(得分:28)

此代码适用于大多数iOS版本(已经过测试,可以在3.1版本上运行)。

它基于Apple WWDC code for PhotoScroller

将以下内容添加到UIScrollView的子类中,并将tileContainerView替换为包含图片或图块的视图:

- (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;
}

答案 1 :(得分:2)

您是否检查过UIViewAutoresizing选项?

(来自文档)

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;

答案 2 :(得分:1)

您使用IB添加滚动视图吗?将scrollview的自动调整选项更改为附加图像。 alt text

答案 3 :(得分:0)

你能解决这个问题吗?我遇到了类似的问题。我认为它背后的原因是因为zoomScale适用于整个contentSize,而不管scrollView中的子视图的实际大小(在你的情况下它是一个imageView)。 contentSize高度似乎总是等于或大于scrollView框架的高度,但从不小。因此,当对它应用缩放时,contentSize的高度也会乘以zoomScale因子,这就是为什么你得到额外的100个像素的垂直滚动。

答案 4 :(得分:-1)

您可能希望设置图像视图的滚动视图=边界的边界,然后将滚动视图置于其包含视图的中心。如果您将视图放置在距离顶部偏移的滚动视图内,您将在其上方获得该空白区域。