Problema de pagination triple anidada UIScrollView

Historia de background
Tengo una aplicación para iPad que debe permitir al usuario navegar por grupos de imágenes. Cada grupo se distribuye en su propio vertical UIScrollView (paginado) para que el usuario pueda deslizar hacia arriba y hacia abajo para ver cada image. Cada uno de los UIScrollViews del grupo se coloca en una UIScrollView (también paginada) horizontal única (solo existe en la aplicación). Esto funciona muy bien … Puedo deslizar hacia arriba y hacia abajo para ver las imágenes en un grupo y deslizar hacia la izquierda y hacia la derecha para ir al grupo siguiente o anterior.

Problema
El problema comenzó cuando necesitaba agregar zoom para cada image. Logré esto colocando cada image dentro de su propio UIScrollView. Cuando la image se amplía, puedo desplazar la image y cuando llego a la parte superior o inferior de la image ampliada, las páginas verticales UIScrollView del grupo a la image siguiente o anterior como se esperaba. Desafortunadamente, la vista de desplazamiento horizontal externa no pasará al siguiente grupo cuando la image se amplía y avanzo hacia el extremo izquierdo o extremo derecho.

¿Hay un enfoque mejor (más correcto) que el UIScrollViews de anidación triple o puedo de alguna manera hacer avanzar los toques a la vista de desplazamiento horizontal externa?

Cualquier ayuda o sugerencia sería muy apreciada.

Espero que no sea demasiado tarde pero creo que tengo una solución para tu problema.

Aquí puede encontrar un proyecto Xcode que muestra la configuration de scrollview que tiene, su problema y la solución propuesta: https://bitbucket.org/reydan/threescrollviews

Básicamente, la solución era agregar 1 píxel a contentSize.width de scrollviews verticales . Esto obliga a la vista de desplazamiento vertical a desplazarse un poco cuando avanza hasta el borde de la image ampliada. Se desplaza un poco y luego continúa a la siguiente vista vertical de desplazamiento.

Si descarga el proyecto, verá que he creado algunas vistas de desplazamiento en el método viewDidLoad . Allí, creo una vista de desplazamiento horizontal que contiene 3 vistas de desplazamiento verticales, cada una con 5 imágenes. Cada image está realmente encapsulada en una vista de desplazamiento para permitir el zoom por image. En total … scrollviews nesteds triples.

También he dejado algunos bordes de colors para que pueda ver fácilmente cómo se desplaza cada scrollview.

  • el magenta = scrollview horizontal
  • el scrollview blanco = vertical
  • el azul = la image scrollview (la que contiene la image y permite hacer zoom)
  • el rojo = el UIImageView

Verá que he labeldo cada vista de desplazamiento de image con el valor 10. Esto se utiliza en la implementación de - (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView delegate method donde return nil less que el evento provenga de uno de los scrollviews de la image .

Si tiene alguna pregunta sobre el proyecto que hice no dude en preguntar.

Al final , me gustaría decir que este método de navigation es un poco peculiar para mí, ya que a veces me desploop en la dirección no deseada. A menudo pienso que moví mi dedo verticalmente para encontrar el scrollview hacia la izquierda o hacia la derecha porque interpretó un pequeño movimiento horizontal que tenía.

El problema que encontré con la pagination habilitada para el movimiento horizontal y vertical es que las vistas de desplazamiento están bloqueadas en la dirección, o eso me pareció a mí.

EDITAR:

Hoy he investigado el problema aún más. Estas son mis conclusiones:

  • no es un problema con el zoom, es un problema tener un contenido más grande en la vista de desplazamiento más interna que el área visible (puede probar esto haciendo zoom o simplemente inicializando el tamaño de contenido más grande que los límites). Esto permite el outlook dentro de la vista de desplazamiento más interna y cambia completamente el comportamiento de los events táctiles.

  • el rebote de un marcador de desplazamiento afecta el comportamiento del gesto de desplazamiento (arrastre) cuando alcanza los bordes del contenido. Si bounces=false , su gesto de paneo se detendrá en el borde, no reenviará el evento de arrastre por la cadena (y, por lo tanto, no desplazará las vistas de desplazamiento principales para mostrar otras imágenes). Si bounces=true entonces, cuando llegue al borde y continúe arrastrando, los events se reenviarán a la vista de desplazamiento primaria y esa vista de desplazamiento también se arrastrará. Sin embargo, he descubierto que arrastrando mientras rebota networkinguce la distancia arrastrada aproximadamente en un 50%. Esto también sucede en la aplicación Fotos.

  • si comienza a arrastrar mientras que la vista de desplazamiento más interna está en el borde del contenido, la vista de desplazamiento es inteligente y reenviará todos los events a la vista de desplazamiento primaria.

  • por alguna razón, los scrollviews nesteds triples son problemáticos, ya que los events simplemente no se reenvían entre las vistas de desplazamiento superiores y medias mientras se desplazan dentro de la vista de desplazamiento más interna. No tengo ni idea de porqué.

Mi solución con ese píxel +1 al tamaño del contenido, soluciona parcialmente el problema.

EDITAR 2013

Chico, estas vistas de desplazamiento son algo fuera de este mundo 🙁

Después de más de un año de búsqueda (solo bromas … en realidad eran 2 días), creo que encontré una buena solución elegante para las scrollviews anidadas triples. Creé un proyecto de testing aquí: https://github.com/reydanro/TripleNestedScrollViews

Dentro de la aplicación, hay un interruptor que puede usar para probar con / sin la solución.

La configuration que estoy usando en mi aplicación es un poco diferente a esta pregunta. Tengo 1 scrollview paginado vertical. En su interior, tengo múltiples visores desplazados horizontalmente. Dentro de algunas de las vistas de desplazamiento horizontales tengo otra vista de desplazamiento paginada vertical.

Sin la solución , una vez que llegue a la página con la vista de desplazamiento más interna, estará bastante atrapado allí, ya que los gestos de desplazamiento vertical no se reenviarán al desplazamiento más externo.

La corrección es un UIGestureRecognizer personalizado que debe agregar a las vistas de desplazamiento más internas. Este reconocedor sigue a los events táctiles y si detecta un arrastre más allá del área de contenido, deshabilitará temporalmente el rest de los reconocedores de scrollview. Este es el único método que descubrí para que el scrollview reenvíe los events por la cadena.

El código de reconocimiento de gestos es muy duro con una personalización limitada, pero debería hacer el trabajo. En este momento estoy centrado en la aplicación que desarrollo, pero seguiré actualizando el repository.

PS: No he probado lo que sucede con el zoom, pero no veo ninguna razón por la cual este método no debería funcionar (o estar adaptado para funcionar).