2009-04-27 3 views
19

In meiner Anwendung möchte ich dem Benutzer einen Vollbild-Fotobetrachter präsentieren, der dem in der Fotos App ähnlich ist. Dies ist nur für ein einzelnes Foto und als solches sollte ziemlich einfach sein. Ich möchte nur, dass der Benutzer dieses eine Foto mit der Fähigkeit zum Zoomen und Schwenken sehen kann.Wie zentriere ich eine UIImageView innerhalb eines Vollbild-UIScrollView?

Ich habe das meiste davon funktioniert. Und wenn ich meinen UIImageView nicht zentriere, verhält sich alles perfekt. Ich möchte jedoch wirklich, dass das UIImageView auf dem Bildschirm zentriert wird, wenn das Bild ausreichend herausgezoomt ist. Ich möchte nicht, dass es in der oberen linken Ecke der Bildlaufansicht bleibt.

Sobald ich versuche, diese Ansicht zu zentrieren, scheint mein vertikaler scrollbarer Bereich größer zu sein als er sein sollte. Wenn ich also ein wenig heranzoomen kann, kann ich ungefähr 100 Pixel über den oberen Rand des Bildes scrollen. Was mache ich falsch?

@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

Was ist der setZoomScale Anruf? Benutzt du meine ZoomScrollView? –

Antwort

26

Dieser Code auf den meisten Versionen von iOS funktionieren soll (und wurde auf 3.1 nach oben arbeiten getestet).

Es basiert auf der Apple WWDC code for PhotoScroller.

Fügen Sie die unten an der Unterklasse von UIScrollView und ersetzen tileContainerView mit der Ansicht mit Ihrem Bild oder Fliesen:

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

Schön, funktionierte eine Belohnung. – kim3er

+0

Das funktioniert perfekt und ich benutze es die ganze Zeit. – bentford

+0

Thx, die perfekt funktionieren: D –

-1

Sie wollen wahrscheinlich die Grenzen der Bildlaufansicht setzen = Grenzen der Bildansicht und dann in der darin enthaltenen Ansicht die Scroll-Ansicht zentrieren. Wenn Sie eine Ansicht in einer Bildlaufansicht mit einem Versatz von oben platzieren, wird der darüber liegende leere Bereich angezeigt.

+0

Danke, aber das scheint keinen Unterschied zu machen. Aufruf von [scrollView setBounds: [imageView bounds]]; erlaubt mir auch, nach oben und unten zu scrollen, auch wenn das Bild nicht den gesamten vertikalen Raum des Bildschirms einnimmt. –

1

Verwenden Sie IB, um die Bildlaufansicht hinzuzufügen? Ändern Sie die Optionen für die automatische Größenanpassung der Bildlaufansicht in das angehängte Bild. alt text http://img527.imageshack.us/img527/1607/picture1mqc.th.png

+0

Ich verwende nicht IB, um das UIScrollView hinzuzufügen. Ich denke jedoch, dass die Größe der Bildlaufansicht korrekt ist. Wenn ich die Hintergrundfarbe meiner Bildlaufansicht auf Violett ändere, kann ich sehen, dass sie immer den gesamten Bildschirm einnimmt. –

0

Konnten Sie dieses Problem lösen? Ich stehe mit einem ähnlichen Problem fest. Ich denke, der Grund dafür ist, dass die ZoomScale für die gesamte contentSize gilt, unabhängig von der tatsächlichen Größe der Unteransicht innerhalb der scrollView (in Ihrem Fall ist es eine imageView). Die Höhe von contentSize scheint immer gleich oder größer als die Höhe des scrollView-Rahmens zu sein, aber niemals kleiner. Wenn Sie also einen Zoom darauf anwenden, wird die Höhe von contentSize ebenfalls mit dem zoomScale-Faktor multipliziert, deshalb erhalten Sie zusätzliche 100 Pixel vertikaler Scroll.

2

Haben Sie die UIViewAutoresizing-Optionen ausgecheckt?

(aus der Dokumentation)

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;