UIScrollView desplácese hacia abajo mediante progtwigción

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

Puede usar la función setContentOffset:animated: UIScrollView para desplazarse a cualquier parte de la vista de contenido. Aquí hay un código que se desplazaría hacia abajo, asumiendo que 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 pegar copias fácilmente:

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

La solución más simple:

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

Simplemente 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 ocupa del recuadro inferior (en caso de que lo estés usando para ajustar tu vista de desplazamiento cuando el teclado está visible)

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

La solución correcta es desplazar la parte inferior del contenido hasta la parte inferior de la vista de desplazamiento, así ( sv es 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]; } 

Una solución Swift 2.2, teniendo en cuenta contentInset

 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 cuenta que es posible que desee comprobar si bottomOffset.y > 0 antes del desplazamiento

Vuelve al comienzo

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

Desplazarse hacia abajo

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

Una implementación rápida:

 extension UIScrollView { func scrollToBottom(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) } } 

Llamas a la extensión de esta manera:

 yourScrollview.scrollToBottom(animated: true) 

¿Qué contentSize si contentSize es menor que los bounds ?

Para Swift es:

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

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

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

Utilizando setContentOffset:animated: de UIScrollView setContentOffset:animated: función 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) 

Con un (opcional) footerView y contentInset, 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]; 

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 al rescate!

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

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

Y luego a esa implementación de la 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 impleméntalo donde quieras, por ejemplo:

 [[myWebView scrollView] scrollToBottomAnimated:YES]; 

Una buena manera de asegurarse de que la parte inferior de su contenido esté visible es usar la fórmula:

 contentOffsetY = MIN(0, contentHeight - boundsHeight) 

Esto garantiza que el borde inferior de su contenido esté siempre en o sobre el borde inferior de la vista. Se requiere el MIN(0, ...) porque UITableView (y probablemente UIScrollView ) garantiza contentOffsetY >= 0 cuando el usuario intenta desplazarse visiblemente contentOffsetY = 0 . Esto se ve bastante extraño 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 animación, esto funciona:

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

Si bien la solución Matt me parece correcta, debe tener en cuenta también el recuadro de vista de colección si hay uno que se ha 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 al último elemento de una tabla Vista:

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 fuera de los bordes, mostrando una pantalla negra.

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]; 

Descubrí que contentSize realmente no refleja el tamaño real del texto, por lo que cuando intente desplazarse hacia abajo, estará un poco apagado. La mejor forma de determinar el tamaño del contenido real es utilizar el NSLayoutManager de usedRectForTextContainer: :

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

Para determinar la cantidad de texto que realmente se muestra en UITextView , puede calcularlo restando las inserciones de contenedor de texto de la altura del marco.

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

Entonces es 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 números para referencia sobre qué 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 rápido:

  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) } 

Versión de Xamarin.iOS para uiCollectionView de la respuesta aceptada para facilitar la copia y el pegado

var bottomOffset = new CGPoint (0, CollectionView.ContentSize.Height – CollectionView.Frame.Size.Height + CollectionView.ContentInset.Bottom);

CollectionView.SetContentOffset (bottomOffset, false);

Versión de Xamarin.iOS de la respuesta aceptada

 var bottomOffset = new CGPoint (0, scrollView.ContentSize.Height - scrollView.Frame.Size.Height + scrollView.ContentInset.Bottom); scrollView.SetContentOffset (bottomOffset, false);