簡體   English   中英

如何在全屏 UIScrollView 中居中 UIImageView?

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

在我的應用程序中,我想向用戶展示一個全屏照片查看器,就像照片應用程序中使用的那樣。 這僅適用於單張照片,因此應該非常簡單。 我只希望用戶能夠通過縮放和平移功能查看這張照片。

我有大部分工作。 而且,如果我不將 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

這段代碼應該適用於大多數 iOS 版本(並且已經過測試可以在 3.1 以上版本上工作)。

它基於PhotoScrollerApple WWDC 代碼

將以下內容添加到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;
}

您是否檢查過 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;

您是否使用 IB 添加滾動視圖? 將滾動視圖的自動調整選項更改為附加圖像。 替代文字

我認為其背后的原因是因為 zoomScale 適用於整個 contentSize,而不管 scrollView 內子視圖的實際大小(在您的情況下它是一個 imageView)。 contentSize 高度似乎總是等於或大於 scrollView 框架的高度,但永遠不會更小。 因此,當對其應用縮放時, contentSize 的高度也會乘以 zoomScale 因子,這就是為什么您會獲得額外的 100 像素左右的垂直滾動。

您可能希望設置滾動視圖的邊界 = 圖像視圖的邊界,然后將滾動視圖置於其包含視圖的中心。 如果您將視圖放置在滾動視圖內與頂部偏移的位置,您將在其上方獲得空白空間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM