ios objective-c uiscrollview

ios - UIScrollView desplaza hacia abajo programáticamente



objective-c (24)

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


¿Qué pasa si contentSize es más bajo que los bounds ?

Para Swift es:

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


Categoría al rescate!

Agregue esto a un encabezado de utilidad compartida en algún lugar:

@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 implementalo donde quieras, por ejemplo:

[[myWebView scrollView] scrollToBottomAnimated:YES];


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


Descubrí que contentSize no refleja realmente el tamaño real del texto, por lo que cuando intente desplazarse hacia abajo, quedará un poco apagado. La mejor manera de determinar el tamaño del contenido real es usar 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 el UITextView , puede calcularlo restando las inserciones del 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 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 números para referencia sobre 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 veloz

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


La configuración del desplazamiento del contenido a la altura del tamaño del contenido es incorrecta: desplaza la parte inferior del contenido hasta la parte superior de la vista de desplazamiento y, por lo tanto, desaparece.

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


La solución más simple:

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


No funcionó para mí, cuando intenté usarlo en UITableViewController en self.tableView (iOS 4.1) , después de agregar footerView . Se desplaza fuera de 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];


Puede usar la función setContentOffset:animated: UIScrollView para desplazarse a cualquier parte de la vista de contenido. Aquí hay algunos códigos que se desplazarían al final, asumiendo que su scrollView es self.scrollView :

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

¡Espero que ayude!


Si bien la solución de Matt me parece correcta, también debe tener en cuenta el recuadro de la vista de colección si hay uno que se haya 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]; }


Si no necesitas animación, esto funciona:

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


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 de la inserción inferior (en caso de que esté utilizando eso para ajustar su vista de desplazamiento cuando el teclado está visible)


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


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

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


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

contentOffsetY = MIN(0, contentHeight - boundsHeight)

Esto asegura que el borde inferior de su contenido esté siempre en o por encima del borde inferior de la vista. Se requiere el MIN(0, ...) porque UITableView (y probablemente UIScrollView ) garantiza contentOffsetY >= 0 cuando el usuario intenta desplazarse haciendo un snapping 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]; }


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 así:

yourScrollview.scrollToBottom(animated: true)


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 de desplazarse


Usando la función setContentOffset:animated: UIScrollView para desplazarse a la parte inferior en Swift.

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


Versión de UICollectionView 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 respuesta aceptada.

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


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

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


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


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


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