2009-04-27 7 views
19

Dans mon application, je voudrais présenter à l'utilisateur une visionneuse de photos en plein écran un peu comme celle utilisée dans l'application Photos. Ceci est juste pour une seule photo et en tant que telle devrait être assez simple. Je veux juste que l'utilisateur puisse voir cette photo avec la possibilité de zoomer et de faire un panoramique.Comment centrer un UIImageView dans un UIScrollView plein écran?

J'ai la plupart de travail. Et, si je ne centre pas mon UIImageView, tout se comporte parfaitement. Cependant, je veux vraiment que UIImageView soit centré sur l'écran lorsque l'image est suffisamment agrandie. Je ne veux pas qu'il reste bloqué dans le coin supérieur gauche de la vue déroulante.

Une fois que j'essaye de centrer cette vue, ma zone défilante verticale semble être plus grande qu'elle ne devrait l'être. En tant que tel, une fois que je zoome un peu, je suis capable de faire défiler environ 100 pixels après le haut de l'image. Qu'est-ce que je fais 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

Qu'est-ce que l'appel de setZoomScale? Utilisez-vous mon ZoomScrollView? –

Répondre

26

Ce code devrait fonctionner sur la plupart des versions d'iOS (et a été testé pour fonctionner sur 3.1 vers le haut). Il est basé sur Apple WWDC code for PhotoScroller.

Ajouter le ci-dessous à votre sous-classe de UIScrollView et remplacer tileContainerView avec la vue contenant votre image ou de tuiles:

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

Belle, a travaillé un régal. – kim3er

+0

Cela fonctionne parfaitement et je l'utilise tout le temps. – bentford

+0

thx qui fonctionnent parfaitement: D –

-1

Vous voulez probablement définir les limites de la vue de défilement = limites de la vue de l'image, puis centrer la vue de défilement dans sa vue contenant. Si vous placez une vue à l'intérieur d'une vue de défilement à un décalage du haut, vous obtiendrez cet espace vide au-dessus.

+0

Merci, mais cela ne semble pas faire de différence. Appel de [scrollView setBounds: [limites d'imageView]]; me permet toujours de faire défiler vers le haut et vers le bas même lorsque l'image ne prend pas tout l'espace vertical de l'écran. –

1

Utilisez-vous IB pour ajouter la vue déroulante? Changez les options de numérisation automatique de la vue déroulante à l'image jointe. alt text http://img527.imageshack.us/img527/1607/picture1mqc.th.png

+0

Je n'utilise pas IB pour ajouter l'UIScrollView. Cependant, je pense que la taille de la vue de défilement est correcte. Lorsque je change la couleur d'arrière-plan de ma vue de défilement en violet, je peux voir qu'elle occupe toujours tout l'écran. –

0

Avez-vous réussi à résoudre ce problème? Je suis coincé avec un problème similaire. Je pense que la raison derrière cela est que le zoomScale s'applique à l'ensemble contentSize, indépendamment de la taille réelle de la sous-vue à l'intérieur de la scrollView (dans votre cas, c'est un imageView). La hauteur contentSize semble être toujours égale ou supérieure à la hauteur du cadre scrollView, mais jamais plus petite. Ainsi, lorsque vous appliquez un zoom, la hauteur de la propriété contentSize est également multipliée par le facteur zoomScale, c'est pourquoi vous obtenez un pixel vertical de plus de 100 pixels.

2

Avez-vous vérifié les options UIViewAutoresizing?

(de la documentation)

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;