iphone - español - Detectar la dirección del desplazamiento de UIScrollView en scrollViewWillBeginDragging
cocoa touch tutorial (9)
Eche un vistazo a scrollViewWillEndDragging:withVelocity:targetContentOffset:
Puede usar ese método para hacer cualquier comprobación y ver si va hacia donde no debería y luego, en el método, puede establecer un nuevo targetContentOffset
.
Según la documentación :
Este método no se invoca cuando el valor de la propiedad pagingEnabled de la vista de desplazamiento es SÍ. Su aplicación puede cambiar el valor del parámetro targetContentOffset para ajustar donde la vista de desplazamiento termina su animación de desplazamiento.
Hice lo suficiente en Google, y verifiqué publicaciones como estas (¿ Buscando la dirección del desplazamiento en un UIScrollView? ) En stackoverflow antes de publicar esto. Tengo una cantidad dinámica de fotos en una aplicación de iPhone que se muestra a través de UIScrollView
. En cualquier momento, solo tengo 3 fotos mostradas en la vista de desplazamiento. Cuando tengo, digamos 4 fotos, en total: 1ra foto: mostrada en offset 0,0 2da foto: mostrada en offset 320.0 3ra foto: mostrada en offset 640,0
Ahora, cuando el usuario se desplaza a la 4ta foto, la vista de desplazamiento se restablece a 0,0 desplazamiento. Si el usuario intenta desplazarse ''más allá'' de la 4ta foto, el desplazamiento debe detenerse solo en la dirección correcta (para que el usuario no se desplace ''más allá''). Pero actualmente, el usuario ''puede'' desplazarse más allá de la última foto; sin embargo, detecto esto programáticamente y reinicio el desplazamiento. Pero no se ve limpio, ya que el usuario ve el fondo negro momentáneamente. Quiero detectar que el usuario ha comenzado a desplazarse ''a la derecha'' (recuerde, desplazarse ''a la izquierda'', es decir, a la foto ''anterior'' está bien) en scrollViewWillBeginDragging
, para que pueda detener cualquier desplazamiento hacia la derecha.
Lo que intenté:
- Intentar usar
self.scrollView.panGestureRecognizer
''stranslationInView
no funciona, porque no sepanGestureRecognizer
instancia depanGestureRecognizer
en primer lugar (!), Aunque la API de UIScrollView así lo afirma. - Detectar esto en
scrollViewDidEndDecelerating
es posible, aunque no servirá para mi propósito.
Esto es lo que usé y funciona muy bien al menos en iOS 6.0:
- (void)scrollViewDidScroll:(UIScrollView*)scrollView
{
CGPoint translation = [scrollView.panGestureRecognizer translationInView:scrollView];
// Detect direction by accessing x or y of translation
}
Te guarda la variable de instancia para lastContentOffset
...
Gracias, Kris. Esto es lo que funcionó para mí, finalmente:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// Detect the scroll direction
if (lastContentOffset < (int)scrollView.contentOffset.x) {
...
}
}
No tuve problemas para determinar la dirección en scrollViewWillBeginDragging
al revisar scrollViewWillBeginDragging
la vista de panGestureRecognizer
:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
CGPoint translation = [scrollView.panGestureRecognizer translationInView:scrollView.superview];
if(translation.y > 0)
{
// react to dragging down
} else
{
// react to dragging up
}
}
Lo encontré muy útil para cancelar un desplazamiento en el primer movimiento de arrastre cuando el usuario está arrastrando en una dirección prohibida.
Para swift 2.0+ y ios 8.0+
func scrollViewWillBeginDecelerating(scrollView: UIScrollView) {
let actualPosition = scrollView.panGestureRecognizer.translationInView(scrollView.superview)
if (actualPosition.y > 0){
// Dragging down
}else{
// Dragging up
}
}
Parece que hay problemas con la detección de la dirección de desplazamiento en función de la traducción del reconocedor de pan scrollView en iOS 7+. Esto parece estar funcionando bastante bien para mis propósitos.
func scrollViewDidScroll(scrollView: UIScrollView) {
if !scrollDirectionDetermined {
let translation = scrollView.panGestureRecognizer.translationInView(self.view)
if translation.y > 0 {
println("UP")
scrollDirectionDetermined = true
}
else if translation.y < 0 {
println("DOWN")
scrollDirectionDetermined = true
}
}
}
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
scrollDirectionDetermined = false
}
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
scrollDirectionDetermined = false
}
Partiendo de la respuesta de @ Oscar, puedes hacer cosas como
scrollView.bounces = actualPosition.y < 0
si desea que scrollView rebote cuando se desplaza hacia abajo pero no cuando se desplaza hacia arriba
scrollView.panGestureRecognizer translationInView:scrollView
no informa nada útil en scrollViewWillBeginDragging
en iOS 7.
Esto hace:
En la @interface
BOOL scrollDirectionDetermined;
y:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (!scrollDirectionDetermined) {
if ([scrollView.panGestureRecognizer translationInView:scrollView.superview].x > 0) {
//scrolling rightwards
} else {
//scrolling leftwards
}
scrollDirectionDetermined = YES;
}
}
y:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
scrollDirectionDetermined = NO;
}
Solución Swift 3
1- Añadir UIScrollViewDelegate
2- Añadir este código
func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
let actualPosition = scrollView.panGestureRecognizer.translation(in: scrollView.superview)
if (actualPosition.y > 0){
// Dragging down
}else{
// Dragging up
}
}