2009-04-27 8 views
19

En mi aplicación, me gustaría presentar al usuario un visor de fotos de pantalla completa muy parecido al que se usa en la aplicación Fotos. Esto es solo para una sola foto y como tal debería ser bastante simple. Solo quiero que el usuario pueda ver esta foto con la capacidad de acercar y alejar.¿Cómo centro un UIImageView dentro de una pantalla completa UIScrollView?

Tengo casi todo funcionando. Y, si no centro mi UIImageView, todo se comporta perfectamente. Sin embargo, realmente quiero que el UIImageView se centre en la pantalla cuando la imagen esté suficientemente alejada. No quiero que se pegue a la esquina superior izquierda de la vista de desplazamiento.

Una vez que intento centrar esta vista, mi área vertical desplazable parece ser mayor de lo que debería ser. Como tal, una vez que acerco un poco, puedo desplazar unos 100 píxeles más allá de la parte superior de la imagen. ¿Qué estoy haciendo mal?

@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

¿Cuál es esa llamada setZoomScale? ¿Estás usando mi ZoomScrollView? –

Respuesta

26

Este código debería funcionar en la mayoría de las versiones de IOS (y ha sido probado para trabajar en 3.1 arriba).

Se basa en el Apple WWDC code for PhotoScroller.

Añadir el siguiente a su subclase de UIScrollView, y reemplace tileContainerView con la vista que contiene la imagen o azulejos:

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

Hermoso, trabajado un lujo. – kim3er

+0

Esto funciona perfectamente y lo uso todo el tiempo. – bentford

+0

thx que funcionan perfectamente: D –

-1

es probable que desee establecer los límites de la vista de desplazamiento = límites de la vista de la imagen, y luego centrar la vista de desplazamiento en su opinión que contiene. Si coloca una vista dentro de una vista de desplazamiento en un desplazamiento desde la parte superior, obtendrá ese espacio vacío encima de ella.

+0

Gracias, pero eso no parece hacer ninguna diferencia. Llamar a [scrollView setBounds: [límites de imageView]]; todavía me permite desplazarme hacia arriba y hacia abajo incluso cuando la imagen no ocupa todo el espacio vertical de la pantalla. –

1

¿Está utilizando IB para agregar la vista de desplazamiento? Cambie las opciones de autosizing de la vista de desplazamiento a la imagen adjunta. alt text http://img527.imageshack.us/img527/1607/picture1mqc.th.png

+0

No estoy usando IB para agregar UIScrollView. Sin embargo, creo que el tamaño de la vista de desplazamiento es correcto. Cuando cambio el color de fondo de mi vista de desplazamiento a púrpura, puedo ver que siempre ocupa toda la pantalla. –

0

¿Pudo resolver este problema? Estoy atrapado con un problema similar. Creo que la razón detrás de esto es porque el zoomScale se aplica a todo el tamaño del contenido, independientemente del tamaño real de la subvista dentro del scrollView (en su caso, es un imageView). La altura contentSize parece ser siempre igual o mayor que la altura del marco scrollView, pero nunca más pequeña. Por eso, al aplicarle un zoom, la altura del contentSize también se multiplica por el factor zoomScale, es por eso que obtiene más de 100 y algo píxeles de desplazamiento vertical.

2

¿Has comprobado las opciones de UIViewAutoresizing?

(a partir de la documentación)

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; 
Cuestiones relacionadas