2009-04-27 4 views
19

Nella mia applicazione, vorrei presentare all'utente un visualizzatore di foto a schermo intero simile a quello utilizzato nell'app Foto. Questo è solo per una singola foto e come tale dovrebbe essere abbastanza semplice. Voglio solo che l'utente sia in grado di visualizzare questa foto con la possibilità di zoomare e panoramica.Come si centra UIImageView in un UIScrollView a schermo intero?

Ho quasi tutto funzionante. E, se non centrassi il mio UIImageView, tutto si comporta perfettamente. Tuttavia, voglio davvero che UIImageView sia centrato sullo schermo quando l'immagine è sufficientemente ingrandita. Non voglio che sia bloccato nell'angolo in alto a sinistra della visualizzazione di scorrimento.

Una volta che tento di centrare questa vista, la mia area di scorrimento verticale sembra essere più grande di quanto dovrebbe essere. Come tale, una volta ingrandito un po ', sono in grado di scorrere di circa 100 pixel oltre la parte superiore dell'immagine. Che cosa sto facendo di sbagliato?

@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

Cosa c'è quella chiamata setZoomScale? Stai usando il mio ZoomScrollView? –

risposta

26

Questo codice dovrebbe funzionare sulla maggior parte delle versioni di iOS (ed è stato testato per funzionare su 3.1 verso l'alto).

Si basa su Apple WWDC code for PhotoScroller.

Aggiungere il seguente per la vostra sottoclasse di UIScrollView, e sostituire tileContainerView con la vista contenente l'immagine o piastrelle:

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

Bello, ha funzionato a meraviglia. – kim3er

+0

Funziona perfettamente e lo uso sempre. – bentford

+0

thx che funziona perfettamente: D –

-1

probabilmente si desidera impostare dei limiti della vista di scorrimento = limiti della visualizzazione dell'immagine, e poi centrare la vista di scorrimento a suo avviso contenente. Se si posiziona una vista all'interno di una vista di scorrimento con un offset dall'alto, si otterrà lo spazio vuoto sopra di esso.

+0

Grazie, ma questo non sembra fare alcuna differenza. Chiamando [scrollView setBounds: [imageView bounds]]; mi consente comunque di scorrere su e giù anche quando l'immagine non occupa l'intero spazio verticale dello schermo. –

1

Stai utilizzando IB per aggiungere la vista di scorrimento? Cambia le opzioni di autosizing della scrollview con l'immagine allegata. alt text http://img527.imageshack.us/img527/1607/picture1mqc.th.png

+0

Non sto utilizzando IB per aggiungere UIScrollView. Tuttavia, penso che la dimensione della vista di scorrimento sia corretta. Quando cambio il colore di sfondo della mia vista di scorrimento in viola, posso vedere che occupa sempre l'intero schermo. –

0

Sei riuscito a risolvere questo problema? Sono bloccato con un problema simile. Penso che la ragione di ciò sia perché lo zoomScale si applica all'intero contentSize, indipendentemente dalle dimensioni effettive della sottoview all'interno della scrollView (nel tuo caso è un imageView). L'altezza di contentSize sembra essere sempre uguale o maggiore dell'altezza del frame ScrollView, ma mai più piccola. Quindi, quando si applica uno zoom ad esso, l'altezza di contentSize viene moltiplicata per il fattore di zoomScale, ecco perché si ottengono 100 pixel di scroll verticale in più.

2

Avete verificato le opzioni di UIViewAutoresizing?

(dalla documentazione)

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;