¿Cómo hago un desplazamiento UIScrollView a la parte superior?
¿Cómo hago un desplazamiento UIScrollView a la parte superior?
Respuestas:
[self.scrollView setContentOffset:
CGPointMake(0, -self.scrollView.contentInset.top) animated:YES];
[self.scrollView setContentOffset:CGPointZero animated:YES];
o si desea preservar la posición de desplazamiento horizontal y simplemente restablecer la posición vertical:
[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, 0)
animated:YES];
[scrollView setContentOffset:CGPointMake(0, -scrollView.contentInset.top) animated:YES];
Funciona en iOS 6 y 7
[scrollView setContentOffset:CGPointMake(0, scrollView.contentSize.height-scrollView.frame.size.height) animated:YES];
Aquí hay una extensión Swift que lo hace fácil:
extension UIScrollView {
func scrollToTop() {
let desiredOffset = CGPoint(x: 0, y: -contentInset.top)
setContentOffset(desiredOffset, animated: true)
}
}
Uso:
myScrollView.scrollToTop()
intenta trabajar con el nuevo adjustedContentInset
.
Por ejemplo (desplazarse hacia arriba):
var offset = CGPoint(
x: -scrollView.contentInset.left,
y: -scrollView.contentInset.top)
if #available(iOS 11.0, *) {
offset = CGPoint(
x: -scrollView.adjustedContentInset.left,
y: -scrollView.adjustedContentInset.top)
}
scrollView.setContentOffset(offset, animated: true)
Incluso si usas
prefersLargeTitles
,safe area
etc.
Para Swift 4
scrollView.setContentOffset(.zero, animated: true)
Utilizar setContentOffset:animated:
[scrollView setContentOffset:CGPointZero animated:YES];
Respuesta para Swift 2.0 / 3.0 / 4.0 y iOS 7+:
let desiredOffset = CGPoint(x: 0, y: -self.scrollView.contentInset.top)
self.scrollView.setContentOffset(desiredOffset, animated: true)
En iOS7 tuve problemas para obtener una vista de desplazamiento particular para ir a la parte superior, que funcionó en iOS6, y usé esto para configurar la vista de desplazamiento para ir a la parte superior.
[self.myScroller scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
Versión Swift 3.0.1 de la respuesta de rob mayoff :
self.scrollView.setContentOffset(
CGPoint(x: 0,y: -self.scrollView.contentInset.top),
animated: true)
Para replicar completamente el comportamiento scrollToTop de la barra de estado, no solo tenemos que configurar contentOffset, sino que también queremos asegurarnos de que se muestren los scrollIndicators. De lo contrario, el usuario puede perderse rápidamente.
El único método público para lograr esto es flashScrollIndicators
. Desafortunadamente, llamarlo una vez después de configurar contentOffset no tiene ningún efecto porque se restablece de inmediato. Descubrí que funciona cuando hago el flash cada vez scrollViewDidScroll:
.
// define arbitrary tag number in a global constants or in the .pch file
#define SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG 19291
- (void)scrollContentToTop {
[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.scrollView.contentInset.top) animated:YES];
self.scrollView.tag = SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.scrollView.tag = 0;
});
}
En su UIScrollViewDelegate (o UITable / UICollectionViewDelegate) implemente esto:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.tag == SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG) {
[scrollView flashScrollIndicators];
}
}
El retraso de ocultar es un poco más corto en comparación con el comportamiento scrollToTop de la barra de estado, pero aún se ve bien.
Tenga en cuenta que estoy abusando de la etiqueta de vista para comunicar el estado "isScrollingToTop" porque necesito esto en los controladores de vista. Si está usando etiquetas para otra cosa, es posible que desee reemplazar esto con un iVar o una propiedad.
Creo que tengo una respuesta que debería ser totalmente compatible con iOS 11, así como con versiones anteriores (para desplazamiento vertical)
Esto tiene en cuenta el nuevo ajustadoContentInset y también tiene en cuenta el desplazamiento adicional requerido cuando prefiereLargeTitles está habilitado en la de navegación, que parece requerir un desplazamiento adicional de 52 píxeles además del valor predeterminado.
Esto fue un poco complicado porque el ajustadoContentInset cambia según el estado de titleBar (título grande vs título pequeño), por lo que necesitaba verificar y ver cuál era la altura de titleBar y no aplicar el desplazamiento de 52px si ya está en el estado grande. No se pudo encontrar ningún otro método para verificar el estado de la barra de navegación, por lo que si alguien tiene una mejor opción que ver si la altura es> 44.0, me gustaría escucharla.
func scrollToTop(_ scrollView: UIScrollView, animated: Bool = true) {
if #available(iOS 11.0, *) {
let expandedBar = (navigationController?.navigationBar.frame.height ?? 64.0 > 44.0)
let largeTitles = (navigationController?.navigationBar.prefersLargeTitles) ?? false
let offset: CGFloat = (largeTitles && !expandedBar) ? 52: 0
scrollView.setContentOffset(CGPoint(x: 0, y: -(scrollView.adjustedContentInset.top + offset)), animated: animated)
} else {
scrollView.setContentOffset(CGPoint(x: 0, y: -scrollView.contentInset.top), animated: animated)
}
}
Inspirado en la solución de Jakub
Es muy común cuando su barra de navegación se superpone a la pequeña porción del contenido scrollView y parece que el contenido no comienza desde la parte superior. Para arreglarlo hice 2 cosas:
Desplazarse hasta parte superior de UITableViewController
, UICollectionViewController
o cualquiera UIViewController
que tengaUIScrollView
extension UIViewController {
func scrollToTop(animated: Bool) {
if let tv = self as? UITableViewController {
tv.tableView.setContentOffset(CGPoint.zero, animated: animated)
} else if let cv = self as? UICollectionViewController{
cv.collectionView?.setContentOffset(CGPoint.zero, animated: animated)
} else {
for v in view.subviews {
if let sv = v as? UIScrollView {
sv.setContentOffset(CGPoint.zero, animated: animated)
}
}
}
}
}
En SWIFT 5, simplemente configure la compensación de contenido en cero
scrollView.setContentOffset(CGPoint.zero, animated: true)
Lo intenté de todas las formas. Pero nada funcionó para mí. Finalmente me gustó esto.
yo añadí self.view .addSubview(self.scroll)
línea de código en el viewDidLoad. Después de comenzar a configurar el marco para la vista de desplazamiento y agregar componentes a la vista de desplazamiento.
Funcionó para mi.
Asegúrese de agregar una self.view .addSubview(self.scroll)
línea al principio. entonces puede agregar elementos de la interfaz de usuario.
UIScrollView
contentInset
, lamentablemente.[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.scrollView.contentInset.top) animated:YES];
hace el trabajo por mí