Domanda

Ho lottato con questo problema per qualche tempo e sembra che ci sia una risposta chiara. Per favore fatemi sapere se qualcuno ha capito questo.

Voglio visualizzare una foto in un UIScrollView che è al centro dello schermo (l'immagine può essere in orientamento verticale o orizzontale).

Voglio essere in grado di zoom e pan l'immagine solo fino al bordo dell'immagine come nella foto app.

Ho provato alterare il contentInset nel metodo viewDidEndZooming e quella sorta di fa il trucco, ma ci sono diversi difetti.

Inoltre ho provato a fare il imageView la stessa dimensione del scrollView e centrare l'immagine lì. Il problema è che quando si esegue lo zoom, è possibile scorrere l'intero imageView e parte dell'immagine può scorrere fuori la vista.

Ho trovato un post simile qui e dato il massimo soluzione, ma è stata trovata alcuna vera risposta:

UIScrollView con UIImageView centrato, come app Foto

È stato utile?

Soluzione 3

Ecco la soluzione migliore che potrei fornire per questo problema. Il trucco è quello di regolare costantemente telaio della ImageView. Trovo che questo funziona molto meglio di regolare costantemente i contentInsets o contentOffSets. Ho dovuto aggiungere un po 'di codice aggiuntivo per accogliere entrambe le immagini ritratto e paesaggio.

Se qualcuno può trovare un modo migliore per farlo, mi piacerebbe sentirlo.

Ecco il codice:

- (void) scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale {

CGSize screenSize = [[self view] bounds].size;

if (myScrollView.zoomScale <= initialZoom +0.01) //This resolves a problem with the code not working correctly when zooming all the way out.
{
    imageView.frame = [[self view] bounds];
    [myScrollView setZoomScale:myScrollView.zoomScale +0.01];
}

if (myScrollView.zoomScale > initialZoom)
{
    if (CGImageGetWidth(temporaryImage.CGImage) > CGImageGetHeight(temporaryImage.CGImage)) //If the image is wider than tall, do the following...
    {
            if (screenSize.height >= CGImageGetHeight(temporaryImage.CGImage) * [myScrollView zoomScale]) //If the height of the screen is greater than the zoomed height of the image do the following...
            {
                    imageView.frame = CGRectMake(0, 0, 320*(myScrollView.zoomScale), 368);
            }
            if (screenSize.height < CGImageGetHeight(temporaryImage.CGImage) * [myScrollView zoomScale]) //If the height of the screen is less than the zoomed height of the image do the following...
            {
                    imageView.frame = CGRectMake(0, 0, 320*(myScrollView.zoomScale), CGImageGetHeight(temporaryImage.CGImage) * [myScrollView zoomScale]);
            }
    }
    if (CGImageGetWidth(temporaryImage.CGImage) < CGImageGetHeight(temporaryImage.CGImage)) //If the image is taller than wide, do the following...
    {
            CGFloat portraitHeight;
            if (CGImageGetHeight(temporaryImage.CGImage) * [myScrollView zoomScale] < 368)
            { portraitHeight = 368;}
            else {portraitHeight = CGImageGetHeight(temporaryImage.CGImage) * [myScrollView zoomScale];}

            if (screenSize.width >= CGImageGetWidth(temporaryImage.CGImage) * [myScrollView zoomScale]) //If the width of the screen is greater than the zoomed width of the image do the following...
            {
                    imageView.frame = CGRectMake(0, 0, 320, portraitHeight);
            }
            if (screenSize.width < CGImageGetWidth (temporaryImage.CGImage) * [myScrollView zoomScale]) //If the width of the screen is less than the zoomed width of the image do the following...
            {
                    imageView.frame = CGRectMake(0, 0, CGImageGetWidth(temporaryImage.CGImage) * [myScrollView zoomScale], portraitHeight);
            }
    }
    [myScrollView setZoomScale:myScrollView.zoomScale -0.01];
}

Ecco come calcolo la scala di zoom minimo nel metodo viewDidLoad.

CGSize photoSize = [temporaryImage size];
CGSize screenSize = [[self view] bounds].size;

CGFloat widthRatio = screenSize.width / photoSize.width;
CGFloat heightRatio = screenSize.height / photoSize.height;
initialZoom = (widthRatio > heightRatio) ? heightRatio : widthRatio;
[myScrollView setMinimumZoomScale:initialZoom];
[myScrollView setZoomScale:initialZoom];
[myScrollView setMaximumZoomScale:3.0];

Altri suggerimenti

Un modo elegante per centrare il contenuto di UISCrollView è questo.

Aggiungi un osservatore alla contentSize della tua UIScrollView, quindi questo metodo sarà chiamato ogni volta che il cambiamento contenuto ...

[myScrollView addObserver:delegate 
               forKeyPath:@"contentSize"
                  options:(NSKeyValueObservingOptionNew) 
                  context:NULL];

Ora sul vostro metodo di osservatore:

- (void)observeValueForKeyPath:(NSString *)keyPath   ofObject:(id)object   change:(NSDictionary *)change   context:(void *)context { 

    // Correct Object Class.
    UIScrollView *pointer = object;

    // Calculate Center.
    CGFloat topCorrect = ([pointer bounds].size.height - [pointer viewWithTag:100].bounds.size.height * [pointer zoomScale])  / 2.0 ;
            topCorrect = ( topCorrect < 0.0 ? 0.0 : topCorrect );

    topCorrect = topCorrect - (  pointer.frame.origin.y - imageGallery.frame.origin.y );

    // Apply Correct Center.
    pointer.center = CGPointMake(pointer.center.x,
                                 pointer.center.y + topCorrect ); }
  • Si dovrebbe cambiare il [pointer viewWithTag:100]. Sostituire con il tuo visualizzare il contenuto UIView.

    • cambia anche imageGallery indicando le dimensioni della finestra.

Questo correggerà il centro del everytime contenuti sua cambio formato.

Nota: L'unico modo in cui questo contenuto non fare funziona molto bene è con funzionalità zoom standard del UIScrollView.

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

E 'basato sul codice di Apple WWDC per l'applicazione PhotoScroll.

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;
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top