Как мне центрировать UIImageView в полноэкранном UIScrollView? - PullRequest
20 голосов
/ 27 апреля 2009

В моем приложении я хотел бы предоставить пользователю полноэкранный просмотрщик фотографий, очень похожий на тот, который используется в приложении "Фотографии". Это только для одной фотографии и как таковой должно быть довольно просто. Я просто хочу, чтобы пользователь мог просматривать эту фотографию с возможностью масштабирования и панорамирования.

У меня большая часть работает. И, если я не центрирую свой 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 ]

28 голосов
/ 13 августа 2010

Этот код должен работать на большинстве версий iOS (и был протестирован на работу с версией 3.1 и выше).

Он основан на коде Apple WWDC для 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 голосов
/ 30 января 2010

Вы проверяли параметры автоматического изменения размера UIView?

(из документации)

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;
1 голос
/ 28 апреля 2009

Используете ли вы IB для добавления вида прокрутки? Измените параметры автоматического изменения размера прокрутки на вложенное изображение. alt text

0 голосов
/ 04 августа 2009

Удалось ли вам решить эту проблему? Я застрял с аналогичной проблемой. Я думаю, что причина этого в том, что zoomScale применяется ко всему contentSize, независимо от фактического размера подпредставления внутри scrollView (в вашем случае это imageView). Высота contentSize, кажется, всегда равна или больше высоты кадра scrollView, но никогда не уменьшается. Поэтому при применении масштабирования к нему высота contentSize умножается и на коэффициент zoomScale, поэтому вы получаете дополнительные 100 с чем-то пикселей вертикальной прокрутки.

0 голосов
/ 28 апреля 2009

Вы, вероятно, хотите установить границы вида прокрутки = границы вида изображения, а затем центрировать вид прокрутки в его содержащем виде. Если вы поместите вид внутри вида прокрутки со смещением от вершины, вы получите это пустое пространство над ним.

...