2012-09-06 8 views
6

Quiero ayuda con mi ejemplo de UIScrollView.contenido salta al alejarse con UIScrollView

Creé un programa simple que se desplaza y amplía el contenido (UIImageView). Funciona bien, excepto que el contenido desaparece con frecuencia en la parte inferior derecha cuando intento alejar la imagen. Pero desde que configuré minimumZoomScale en 1.0f, en realidad no se está alejando, solo el contenido salta fuera de la vista. Y lo que es aún más extraño es que no puedo desplazarme hacia arriba después de esto. Aparentemente, el tamaño del contenido también está en mal estado.

enter image description here

La configuración que tengo en mi código de ejemplo es como en la figura siguiente.

enter image description here

Al revisar el estado después de (intentar) enfocando hacia fuera, encontré dos cosas equivocadas.

  • _scrollView.contentSize es 480x360, que no debe ser menor de 1000x1000
  • _scrollView.bounds saltó a la cima de alguna manera (es decir, _scrollView.bounds.origin.y es siempre 0)

Para hacer frente a los dos elementos arriba, agregué el código siguiente en mi UIScrollViewDelegate y ahora funciona bien.

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view 
{ 
    if(scrollView == _scrollView && view == _contentView) 
    { 
     // Setting ivars for scrollViewDidZoom 
     _contentOffsetBeforeZoom = _scrollView.contentOffset; 
     _scrollViewBoundsBeforeZoom = _scrollView.bounds; 
    } 
} 

- (void)scrollViewDidZoom:(UIScrollView *)scrollView 
{ 
    if(scrollView == _scrollView) 
    { 
     // If you zoom out, there are cases where ScrollView content size becomes smaller than original, 
     // even though minimum zoom scale = 1. In that case, it will mess with the contentOffset as well. 
     if(_scrollView.contentSize.width < CONTENT_WIDTH || _scrollView.contentSize.height < CONTENT_HEIGHT) 
     { 
      _scrollView.contentSize = CGSizeMake(CONTENT_WIDTH, CONTENT_HEIGHT); 
      _scrollView.contentOffset = _contentOffsetBeforeZoom; 
     } 

     // If you zoom out, there are cases where ScrollView bounds goes outsize of contentSize rectangle. 
     if(_scrollView.bounds.origin.x + _scrollView.bounds.size.width > _scrollView.contentSize.width || 
      _scrollView.bounds.origin.y + _scrollView.bounds.size.height > _scrollView.contentSize.height) 
     { 
      _scrollView.bounds = _scrollViewBoundsBeforeZoom; 
     }    
    } 
} 

Sin embargo, ¿tiene que reducirse a esto? Esta es una secuencia muy simple, y es difícil creer que Apple nos exija poner este tipo de esfuerzo. Entonces, mi apuesta es que me estoy perdiendo algo aquí ...

El siguiente es mi código original. ¡Por favor, ayúdame a encontrar lo que estoy haciendo mal (o perder algo)!

#define CONTENT_WIDTH 1000 
#define CONTENT_HEIGHT 1000 

    >>>> Snip >>>> 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 

    _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)]; 
    _scrollView.contentSize = CGSizeMake(CONTENT_WIDTH, CONTENT_HEIGHT); 
    _scrollView.backgroundColor = [UIColor blueColor]; 
    _scrollView.maximumZoomScale = 8.0f; 
    _scrollView.minimumZoomScale = 1.0f; 
    _scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite; 
    _scrollView.scrollEnabled = YES; 
    _scrollView.delegate = self; 
    [self.view addSubview:_scrollView]; 

    _contentView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"sample.jpg"]]; // sample.jpg is 480x360 
    CGPoint center = (CGPoint){_scrollView.contentSize.width/2, _scrollView.contentSize.height/2}; 
    _contentView.center = center; 
    [_scrollView addSubview:_contentView]; 

    _scrollView.contentOffset = (CGPoint) {center.x - _scrollView.bounds.size.width/2, center.y - _scrollView.bounds.size.height/2};   
} 

- (UIView *) viewForZoomingInScrollView:(UIScrollView *)scrollView 
{ 
    if(scrollView == _scrollView) 
    { 
     return _contentView; 
    } 
    return nil; 
} 
+1

¿Ha intentado configurar '_contentView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; '? – Adam

+0

Gracias por la sugerencia. Pero no, no cambia la situación ... – barley

+0

¿Puedo preguntar por qué su 'contentSize' es 1000x1000? – tia

Respuesta

10

Creé un proyecto de muestra rápido y tuve el mismo problema que describió al usar el código que pegó. No sé exactamente cuál es la forma "correcta" de ampliar el zoom en iOS, pero encontré el tutorial this, que dice que debes volver a centrar tu contenido después de que se haya acercado el scrollView. Personalmente, espero que se vuelva a centrar automáticamente, dado que es la vista que está devolviendo en el método de delegado viewForZoomingInScrollView, pero aparentemente no.

- (void)centerScrollViewContents { 
    CGSize boundsSize = _scrollView.bounds.size; 
    CGRect contentsFrame = _contentView.frame; 

    if (contentsFrame.size.width < boundsSize.width) { 
     contentsFrame.origin.x = (boundsSize.width - contentsFrame.size.width)/2.0f; 
    } else { 
     contentsFrame.origin.x = 0.0f; 
    } 

    if (contentsFrame.size.height < boundsSize.height) { 
     contentsFrame.origin.y = (boundsSize.height - contentsFrame.size.height)/2.0f; 
    } else { 
     contentsFrame.origin.y = 0.0f; 
    } 

    _contentView.frame = contentsFrame; 
} 

- (void)scrollViewDidZoom:(UIScrollView *)scrollView { 
    // The scroll view has zoomed, so we need to re-center the contents 
    [self centerScrollViewContents]; 
} 

El código anterior no está escrito por mí, sino simplemente se copia desde el tutorial. Creo que es bastante sencillo. Además, centrar el contenido parece ser mucho más elegante que cambiar constantemente los límites y el tamaño del contenido de la vista de desplazamiento, así que pruébalo.

+0

¡Gracias por la respuesta! Tiene sentido y funcionó bien. Lo único en su respuesta fue que '_scrollView.frame' debería ser' _contentView.frame' en mi contexto. Editaré esa parte y seleccionaré como mi respuesta. – barley

0

Si alguien tiene un problema de rebote al alejar el fondo resultante para mostrar, intente eliminar rebotes (rebotes de zoom) en el Generador de interfaces.

1

Pude solucionar este problema usando la respuesta del delegado que ajustaba las tasas después del zoom ... pero luego recordé que estaba usando el diseño automático, y simplemente agregué restricciones para centrar horizontal y verticalmente (además de las restricciones vincular la imagen a cada borde de la vista de desplazamiento) resolvió el problema sin utilizar los métodos de delegado.

+0

¡La pregunta era de la era del armazón y de los puntales, y me alegra saber que las restricciones resuelven este problema con elegancia ahora! – barley

Cuestiones relacionadas