Nota: La respuesta dada aquí no funciona para mí.
Tengo un UIScrollView (no una vista de tabla, solo algo personalizado), y cuando el usuario realiza ciertas acciones, quiero eliminar cualquier desplazamiento (arrastre o desaceleración) dentro de la vista. He intentado hacer, por ejemplo, esto:
[scrollView scrollRectToVisible:CGRectInset([scrollView bounds], 10, 10) animated:NO];
en la teoría de que, dado un rect que ya se sabe visible, el desplazamiento simplemente se detendrá donde está, pero resulta que esto no tiene ningún efecto; aparentemente, la vista de desplazamiento ve que el rect dado está dentro de los límites y toma ninguna acción. Yo puedo buscar el rollo de parada, si me dan un rect que es definitivamente fuera de los límites actualmente visibles, pero dentro de la contentSize de la vista. Esto parece detener la vista como se esperaba ... pero también hace que salte a otra ubicación. Probablemente podría jugar un poco en los márgenes para que esto funcione razonablemente bien, pero ¿alguien conoce una forma limpia de detener una vista de desplazamiento que está haciendo lo suyo?
Gracias.
fuente
setContentOffset
será suficiente. La vista de desplazamiento redondeará el desplazamiento de contenido automáticamente.La respuesta genérica es, ¡eso no
[scrollView setContentOffset:offset animated:NO]
es lo mismo que[scrollView setContentOffset:offset]
![scrollView setContentOffset:offset animated:NO]
realmente detiene cualquier animación en ejecución.[scrollView setContentOffset:offset]
no detiene ninguna animación en ejecución.scrollView.contentOffset = offset
: no detiene ninguna animación en ejecución.Eso no está documentado en ninguna parte, pero ese es el comportamiento probado en iOS 6.1 y iOS 7.1, probablemente también antes.
Entonces, la solución para detener una animación / desaceleración en ejecución es tan simple como eso:
[scrollView setContentOffset:scrollView.contentOffset animated:NO];
Básicamente lo que dijo David Liu en su respuesta editada. Pero quería dejar en claro que estas dos API NO son iguales.
Swift 3:
scrollView.setContentOffset(scrollView.contentOffset, animated:false)
fuente
Para mí, la respuesta aceptada de David Lui anterior no funcionó para mí. Esto es lo que terminé haciendo:
- (void)killScroll { self.scrollView.scrollEnabled = NO; self.scrollView.scrollEnabled = YES; }
Por lo que vale, estoy usando el simulador de iPhone iOS 6.0.
fuente
supportedInterfaceOrientations
para evitar que los eventos de desplazamiento continúen si el usuario gira el dispositivo mientras se desplaza , lo que a veces es un desastre según lo que esté haciendo.Esto es lo que hago para mis vistas de desplazamiento y todas las demás subclases relacionadas:
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset { *targetContentOffset = scrollView.contentOffset; }
Este los conjuntos
targetContentOffset
a lascrollView
's de desplazamiento de corriente, con lo que el desplazamiento se detenga porque se ha alcanzado el objetivo. De hecho, tiene sentido utilizar un método cuyo propósito sea que los usuarios puedan establecer el objetivocontentOffset
.Rápido
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { targetContentOffset.pointee = scrollView.contentOffset }
fuente
Detén el desplazamiento rápido :
scrollView.setContentOffset(scrollView.contentOffset, animated: false)
fuente
En realidad ... La forma más "moderna" sería ->
scrollview.panGestureRecognizer.enabled = false; scrollview.panGestureRecognizer.enabled = true;
Esto desactiva el reconocimiento de gestos que es responsable de desplazarse por un momento que matará el toque actual. El usuario tendría que levantar el dedo y volver a bajarlo para comenzar a desplazarse nuevamente.
Editar: En realidad, esto simplemente elimina el arrastre actual del usuario, pero no detiene inmediatamente la desaceleración si la vista de desplazamiento se encuentra en este estado actualmente. Para hacer esto, la edición de respuestas aceptadas es prácticamente la mejor manera xD
[scrollview setContentOffset: scrollview.contentOffset animated:false];
fuente
La forma más limpia será subclasificar UIScrollView y proporcionar su propio método setContentOffset. Esto debería transmitir el mensaje, solo si no ha activado su
freeze
propiedad booleana.Al igual que:
BOOL freeze; // and the @property, @synthesize lines.. -(void)setContentOffset:(CGPoint)offset { if ( !freeze ) [super setContentOffset:offset]; }
Luego, para congelar:
scrollView.freeze = YES;
fuente
decelerationRate = 1e10;
while freeze == YES?Esta respuesta funcionó para mí: Desactive la desaceleración de UIScrollView
-(void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{ [scrollView setContentOffset:scrollView.contentOffset animated:YES]; }
fuente
Desactive la interacción del usuario con solo desplazarse. (rápido)
scrollView.isScrollEnabled = false
Desactivar durante la animación de desplazamiento después de arrastrar. (rápido)
var scrollingByVelocity = false func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) { if !scrollingByVelocity { scrollView.setContentOffset(scrollView.contentOffset, animated: false) } }
fuente
He probado estos métodos en collectionview:
self.collectionView.collectionViewLayout.finalizeCollectionViewUpdates()
fuente
Esto me funciona en Swift 4.2 :
func killScroll() { self.scrollView.isScrollEnabled = false; self.scrollView.isScrollEnabled = true; }
... como una extensión:
extension UIScrollView { func killScroll() { self.isScrollEnabled = false; self.isScrollEnabled = true; } }
fuente
Quería deshabilitar el desplazamiento solo cuando una determinada UIView dentro de la vista de desplazamiento es la fuente del toque durante el deslizamiento. Habría requerido bastante refactorización para mover UIView fuera de UIScrollView, ya que teníamos una jerarquía de vista compleja.
Como solución alternativa, agregué un único UIPanGestureRecognizer a la subvista en la que quería evitar el desplazamiento. Este UIPanGestureRecognizer
cancelsTouchesInView
que UIScrollView.Es un poco como un 'truco', pero es un cambio súper fácil, y si está usando un XIB o Storyboard, todo lo que necesita hacer es arrastrar el gesto de panorámica a la subvista en cuestión.
fuente