ios uiscrollview uiscrollviewdelegate

ios - Configurar contentOffset mediante programación desencadena scrollViewDidScroll



uiscrollview uiscrollviewdelegate (6)

Tengo algunos UIScrollView en una página. Puede desplazarlos de forma independiente o bloquearlos juntos y desplazarlos como uno solo. El problema ocurre cuando están bloqueados.

Uso UIScrollViewDelegate y scrollViewDidScroll: para seguir el movimiento. contentOffset el contentOffset de UIScrollView que cambió y luego contentOffset el cambio a otras vistas de desplazamiento estableciendo su propiedad contentOffset para que coincida.

Genial ... excepto que noté muchas llamadas extra. Al cambiar de forma programada el contentOffset de mis vistas de desplazamiento, se activa el método de delegado scrollViewDidScroll: para llamar. Intenté usar setContentOffset:animated: lugar, pero sigo recibiendo el activador del delegado.

¿Cómo puedo modificar mi contentOffsets programmatically para no desencadenar scrollViewDidScroll: :?

Notas de implementación ... Cada UIScrollView es parte de una UIView personalizada que usa un patrón de delegado para devolver la llamada a la subclase UIViewController que se presenta UIViewController que se encarga de coordinar los diversos valores de contentOffset .


¿Qué pasa con el uso de las propiedades existentes de UIScrollView?

if(scrollView.isTracking || scrollView.isDragging || scrollView.isDecelerating) { //your code }


Es posible cambiar el desplazamiento de contenido de un UIScrollView sin desencadenar la devolución de llamada de delegado scrollViewDidScroll: estableciendo los límites de UIScrollView con el origen establecido en el desplazamiento de contenido deseado.

CGRect scrollBounds = scrollView.bounds; scrollBounds.origin = desiredContentOffset; scrollView.bounds = scrollBounds;


Esta no es una respuesta directa a la pregunta, pero si obtiene lo que parecen ser falsos tales mensajes, TAMBIÉN puede deberse a que está cambiando los límites. Estoy usando un código de ejemplo de Apple con un método "tilePages" que elimina y agrega subvista a una vista de desplazamiento. Esto ocasionalmente da como resultado scrollViewDidScroll adicional: los mensajes se llaman de inmediato, por lo que entra en una recursión que seguramente no esperaba. En mi caso, tuve un desagradable accidente imposible de encontrar.

Lo que terminé haciendo fue poner en cola la llamada en la cola principal:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView { if(scrollView == yourScrollView) { // dispatch fixes some recursive call to scrollViewDidScroll in tilePages (related to removeFromSuperView) // The reason can be found here: http://.com/questions/9418311 dispatch_async(dispatch_get_main_queue(), ^{ [self tilePages]; }); } }


Otro enfoque es agregar algo de lógica en su delegado scrollViewDidScroll para determinar si el cambio en el desplazamiento de contenido se activó programáticamente o por el toque del usuario.

  • Agregue una variable booleana ''isManualScroll'' a su clase.
  • Establezca su valor inicial en falso.
  • En scrollViewWillBeginDragging, establézcalo en verdadero.
  • En su scrollViewDidScroll, compruebe que sea verdadero y solo responda si lo es.
  • En scrollViewDidEndDecelerating, establézcalo en falso.
  • En scrollViewWillEndDragging agregue lógica para establecerlo en falso si la velocidad es 0 (ya que no se llamará a scrollViewDidEndDecelerating en este caso).

Simplificando la respuesta de @ Tark, puede colocar la vista de desplazamiento sin scrollViewDidScroll en una línea como esta:

scrollView.bounds.origin = CGPoint(x:0, y:100); // whatever values you''d like


Tratar

id scrollDelegate = scrollView.delegate; scrollView.delegate = nil; scrollView.contentOffset = point; scrollView.delegate = scrollDelegate;

Trabajó para mi.