UIScrollView se desplaza hacia abajo programáticamente

¿Cómo puedo hacer que UIScrollView desplace hacia la parte inferior dentro de mi código? ¿O de una manera más genérica, a cualquier punto de una subvista?

Puede usar la function setContentOffset:animated: UIScrollView setContentOffset:animated: para desplazarse a cualquier parte de la vista de contenido. Aquí hay un código que se desplazaría a la parte inferior, suponiendo que su scrollView es self.scrollView :

 CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height); [self.scrollView setContentOffset:bottomOffset animated:YES]; 

¡Espero que ayude!

Versión rápida de la respuesta aceptada para copyr fácilmente:

 let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height) scrollView.setContentOffset(bottomOffset, animated: true) 

Solución más simple:

 [scrollview scrollRectToVisible:CGRectMake(scrollview.contentSize.width - 1,scrollview.contentSize.height - 1, 1, 1) animated:YES]; 

Establecer el desplazamiento de contenido a la altura del tamaño de contenido es incorrecto: se desplaza la parte inferior del contenido a la parte superior de la vista de desplazamiento y, por lo tanto, se pierde de vista.

La solución correcta es desplazar la parte inferior del contenido a la parte inferior de la vista de desplazamiento, de esta manera ( sv es el UIScrollView):

 CGSize csz = sv.contentSize; CGSize bsz = sv.bounds.size; if (sv.contentOffset.y + bsz.height > csz.height) { [sv setContentOffset:CGPointMake(sv.contentOffset.x, csz.height - bsz.height) animated:YES]; } 

Solo una mejora a la respuesta existente.

 CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.contentInset.bottom); [self.scrollView setContentOffset:bottomOffset animated:YES]; 

También se encarga del recuadro inferior (en caso de que lo esté usando para ajustar la vista de desplazamiento cuando el keyboard esté visible)

Vuelve al comienzo

 - CGPoint topOffset = CGPointMake(0, 0); - [scrollView setContentOffset:topOffset animated:YES]; 

Desplácese hacia abajo

 - CGPoint bottomOffset = CGPointMake(0, scrollView.contentSize.height - self.scrollView.bounds.size.height); - [scrollView setContentOffset:bottomOffset animated:YES]; 

Una solución Swift 2.2, teniendo en count el contenido.

 let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom) scrollView.setContentOffset(bottomOffset, animated: true) 

Esto debería estar en una extensión

 extension UIScrollView { func scrollToBottom() { let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height + contentInset.bottom) setContentOffset(bottomOffset, animated: true) } } 

Tenga en count que es posible que desee comprobar si bottomOffset.y > 0 antes del desplazamiento

También encontré otra forma útil de hacer esto en el caso de que esté utilizando una UITableview (que es una subclass de UIScrollView):

 [(UITableView *)self.view scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES]; 

¿Qué contentSize si contentSize es inferior a los bounds ?

Para Swift es:

 scrollView.setContentOffset(CGPointMake(0, max(scrollView.contentSize.height - scrollView.bounds.size.height, 0) ), animated: true) 

Con una (opcional) footerView y contenidoInset, la solución es:

 CGPoint bottomOffset = CGPointMake(0, _tableView.contentSize.height - tableView.frame.size.height + _tableView.contentInset.bottom); if (bottomOffset.y > 0) [_tableView setContentOffset: bottomOffset animated: YES]; 

Usando UIScrollView's setContentOffset:animated: function para desplazarse hacia abajo en Swift.

 let bottomOffset : CGPoint = CGPointMake(0, scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom) scrollView.setContentOffset(bottomOffset, animated: true) 

Una implementación rápida:

 extension UIScrollView { func scrollToBottom(animated animated: Bool) { if self.contentSize.height < self.bounds.size.height { return } let bottomOffset = CGPoint(x: 0, y: self.contentSize.height - self.bounds.size.height) self.setContentOffset(bottomOffset, animated: animated) } } 

Valdyr, espero que esto te ayude:

 CGPoint bottomOffset = CGPointMake(0, [textView contentSize].height - textView.frame.size.height); if (bottomOffset.y > 0) [textView setContentOffset: bottomOffset animated: YES]; 

Categoría para el rescate!

Agregue esto a un encabezado de utilidad compartido en alguna parte:

 @interface UIScrollView (ScrollToBottom) - (void)scrollToBottomAnimated:(BOOL)animated; @end 

Y luego a esa implementación de utilidad:

 @implementation UIScrollView(ScrollToBottom) - (void)scrollToBottomAnimated:(BOOL)animated { CGPoint bottomOffset = CGPointMake(0, self.contentSize.height - self.bounds.size.height); [self setContentOffset:bottomOffset animated:animated]; } @end 

Luego implementarlo donde quiera, por ejemplo:

 [[myWebView scrollView] scrollToBottomAnimated:YES]; 

Una buena manera de garantizar que la parte inferior de su contenido sea visible es usar la fórmula:

 contentOffsetY = MIN(0, contentHeight - boundsHeight) 

Esto garantiza que el borde inferior de su contenido siempre esté en el borde inferior de la vista o por encima de él. Se requiere el MIN(0, ...) porque UITableView (y probablemente UIScrollView ) garantiza contentOffsetY >= 0 cuando el usuario intenta desplazarse contentOffsetY = 0 . Esto se ve bastante raro para el usuario.

El código para implementar esto es:

 UIScrollView scrollView = ...; CGSize contentSize = scrollView.contentSize; CGSize boundsSize = scrollView.bounds.size; if (contentSize.height > boundsSize.height) { CGPoint contentOffset = scrollView.contentOffset; contentOffset.y = contentSize.height - boundsSize.height; [scrollView setContentOffset:contentOffset animated:YES]; } 

Si no necesita animation, esto funciona:

 [self.scrollView setContentOffset:CGPointMake(0, CGFLOAT_MAX) animated:NO]; 

Si bien la solución de Matt me parece correcta, debe tener en count también el recuadro de la vista de colección si hay uno que haya sido configurado.

El código adaptado será:

 CGSize csz = sv.contentSize; CGSize bsz = sv.bounds.size; NSInteger bottomInset = sv.contentInset.bottom; if (sv.contentOffset.y + bsz.height + bottomInset > csz.height) { [sv setContentOffset:CGPointMake(sv.contentOffset.x, csz.height - bsz.height + bottomInset) animated:YES]; } 

Solución para desplazarse hasta el último elemento de una tabla Ver:

Swift 3:

 if self.items.count > 0 { self.tableView.scrollToRow(at: IndexPath.init(row: self.items.count - 1, section: 0), at: UITableViewScrollPosition.bottom, animated: true) } 

No funcionó para mí, cuando traté de usarlo en UITableViewController en self.tableView (iOS 4.1) , después de agregar footerView . Se desplaza por los bordes, mostrando la pantalla en negro.

Solución alternativa:

  CGFloat height = self.tableView.contentSize.height; [self.tableView setTableFooterView: myFooterView]; [self.tableView reloadData]; CGFloat delta = self.tableView.contentSize.height - height; CGPoint offset = [self.tableView contentOffset]; offset.y += delta; [self.tableView setContentOffset: offset animated: YES]; 
 CGFloat yOffset = scrollView.contentOffset.y; CGFloat height = scrollView.frame.size.height; CGFloat contentHeight = scrollView.contentSize.height; CGFloat distance = (contentHeight - height) - yOffset; if(distance < 0) { return ; } CGPoint offset = scrollView.contentOffset; offset.y += distance; [scrollView setContentOffset:offset animated:YES]; 

Encontré que contentSize no refleja realmente el tamaño real del text, por lo que al tratar de desplazarse al final, será un poco apagado. La mejor manera de determinar el tamaño real del contenido es utilizar el NSLayoutManager de usedRectForTextContainer: método:

 UITextView *textView; CGSize textSize = [textView.layoutManager usedRectForTextContainer:textView.textContainer].size; 

Para determinar cuánto text se muestra realmente en UITextView , puede calcularlo restando los recuadros del contenedor de text de la altura del marco.

 UITextView *textView; UIEdgeInsets textInsets = textView.textContainerInset; CGFloat textViewHeight = textView.frame.size.height - textInsets.top - textInsets.bottom; 

Entonces se vuelve fácil desplazarse:

 // if you want scroll animation, use contentOffset UITextView *textView; textView.contentOffset = CGPointMake(textView.contentOffset.x, textSize - textViewHeight); // if you don't want scroll animation CGRect scrollBounds = textView.bounds; scrollBounds.origin = CGPointMake(textView.contentOffset.x, textSize - textViewHeight); textView.bounds = scrollBounds; 

Algunos numbers de reference en lo que representan los diferentes tamaños para un UITextView vacío.

 textView.frame.size = (width=246, height=50) textSize = (width=10, height=16.701999999999998) textView.contentSize = (width=246, height=33) textView.textContainerInset = (top=8, left=0, bottom=8, right=0) 

En swift:

  if self.mainScroll.contentSize.height > self.mainScroll.bounds.size.height { let bottomOffset = CGPointMake(0, self.mainScroll.contentSize.height - self.mainScroll.bounds.size.height); self.mainScroll.setContentOffset(bottomOffset, animated: true) }