如何在全屏UIScrollView中对齐UIImageView?

问题描述:

在我的应用程序中,我想向用户展示非常像照片应用程序中使用的全屏幕照片查看器。这只是一张照片,因此应该很简单。我只想让用户能够通过缩放和平移功能查看这张照片。如何在全屏UIScrollView中对齐UIImageView?

我大部分工作。而且,如果我不集中我的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 
+0

那是什么setZoomScale电话吗?你在使用ZoomScrollView吗? – 2009-05-10 04:37:09

此代码应在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

美丽,工作的一种享受。 – kim3er 2010-10-05 11:53:34

你可能要设置的滚动视图=图像视图的边界,然后在中心它包含的视图中的滚动视图的边界。如果您将视图放置在顶部偏移处的滚动视图中,则会在其上方获得空的空间。

+0

谢谢,但这似乎没有任何区别。调用[scrollView setBounds:[imageView bounds]];即使图像不占据屏幕的整个垂直空间,仍然允许我上下滚动。 – 2009-04-28 14:24:45

您是否使用IB来添加滚动视图?将滚动视图的自动调整选项更改为附加图像。 alt text http://img527.imageshack.us/img527/1607/picture1mqc.th.png

+0

我不使用IB来添加UIScrollView。不过,我认为滚动视图的大小是正确的。当我将滚动视图的背景颜色更改为紫色时,我可以看到它总是占用整个屏幕。 – 2009-04-28 14:21:01

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

你检查了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;