代码之家  ›  专栏  ›  技术社区  ›  Sebastian Celis

如何在全屏UIScrollView中居中显示UIImageView?

  •  20
  • Sebastian Celis  · 技术社区  · 17 年前

    在我的应用程序中,我想向用户展示一个与照片应用程序中使用的一样的全屏照片查看器。这只是一张照片,因此应该很简单。我只是希望用户能够查看这一张照片的能力,缩放和平移。

    我大部分时间都在工作。而且,如果我的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 回复  |  直到 11 年前
        1
  •  28
  •   ilent2    14 年前

    这段代码应该适用于大多数版本的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;
    }
    
        2
  •  2
  •   Jlam    16 年前

    您是否已签出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;
    
        3
  •  1
  •   Glorfindel Doug L.    7 年前

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

        4
  •  0
  •   Dharman vijay    6 年前

    我认为这背后的原因是因为zoomScale应用于整个contentSize,而不管scrollView中子视图的实际大小(在您的例子中,它是一个imageView)。contentSize的高度似乎总是等于或大于scrollView框架的高度,但从不小于该高度。因此,当对其应用缩放时,contentSize的高度也会乘以zoomScale因子,这就是为什么会得到额外的100多像素的垂直滚动。

        5
  •  -1
  •   Felixyz    17 年前

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