Respuestas:
Puede usar la setContentOffset:animated:
función UIScrollView para desplazarse a cualquier parte de la vista de contenido. Aquí hay un código que se desplazaría hacia abajo, suponiendo que su scrollView sea 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!
CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.contentInset.bottom);
contentSize
es inferior a bounds
. Entonces debería ser así:scrollView.setContentOffset(CGPointMake(0, max(scrollView.contentSize.height - scrollView.bounds.size.height, 0) ), animated: true)
let bottomOffsetY = max(collectionView.contentSize.height - collectionView.bounds.height + collectionView.contentInset.bottom, 0)
Versión rápida de la respuesta aceptada para copiar y pegar 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];
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 su vista de desplazamiento cuando el teclado está visible)
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)
}
}
úsalo:
yourScrollview.scrollToBottom(animated: true)
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, no se ve.
La solución correcta es desplazar la parte inferior del contenido hacia 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];
}
if (sv.contentOffset.y + csz.height > bsz.height) {
?
setContentOffset:
comando lo que importa.
Una solución Swift 2.2, teniendo contentInset
en cuenta
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
¿Qué pasa si contentSize
es menor que bounds
?
Para Swift es:
scrollView.setContentOffset(CGPointMake(0, max(scrollView.contentSize.height - scrollView.bounds.size.height, 0) ), 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];
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];
Usando la setContentOffset:animated:
función UIScrollView 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)
Parece que todas las respuestas aquí no tomaron en cuenta el área segura. Desde iOS 11, iPhone X introdujo un área segura. Esto puede afectar los scrollView's contentInset
.
Para iOS 11 y superior, para desplazarse correctamente hasta la parte inferior con el contenido incluido. Deberías usar en adjustedContentInset
lugar de contentInset
. Comprueba este código:
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.height + scrollView.adjustedContentInset.bottom)
scrollView.setContentOffset(bottomOffset, animated: true)
CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.adjustedContentInset.bottom);
[self.scrollView setContentOffset:bottomOffset animated:YES];
contentOffset.x
):extension UIScrollView {
func scrollsToBottom(animated: Bool) {
let bottomOffset = CGPoint(x: contentOffset.x,
y: contentSize.height - bounds.height + adjustedContentInset.bottom)
setContentOffset(bottomOffset, animated: animated)
}
}
Referencias
Rápido:
Podrías usar una extensión como esta:
extension UIScrollView {
func scrollsToBottom(animated: Bool) {
let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height)
setContentOffset(bottomOffset, animated: animated)
}
}
Utilizar:
scrollView.scrollsToBottom(animated: true)
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 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éntelo donde quiera, por ejemplo:
[[myWebView scrollView] scrollToBottomAnimated:YES];
Para vista de desplazamiento horizontal
Si me gusta tiene una vista de desplazamiento horizontal y desea desplazarse hasta el final (en mi caso, a la derecha), debe cambiar algunas partes de la respuesta aceptada:
C objetivo
CGPoint rightOffset = CGPointMake(self.scrollView.contentSize.width - self.scrollView.bounds.size.width + self.scrollView.contentInset.right, 0 );
[self.scrollView setContentOffset:rightOffset animated:YES];
Rápido
let rightOffset: CGPoint = CGPoint(x: self.scrollView.contentSize.width - self.scrollView.bounds.size.width + self.scrollView.contentInset.right, y: 0)
self.scrollView.setContentOffset(rightOffset, animated: true)
Si de alguna forma cambiar ScrollView contentSize (ej. Añadir algo a stackView que está dentro ScrollView) debe llamar scrollView.layoutIfNeeded()
antes de desplazarse, de lo contrario, no hace nada.
Ejemplo:
scrollView.layoutIfNeeded()
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom)
if(bottomOffset.y > 0) {
scrollView.setContentOffset(bottomOffset, animated: true)
}
Una buena manera de asegurarse de 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 esté siempre en o por encima del borde inferior de la vista. Se MIN(0, ...)
requiere porque UITableView
(y probablemente UIScrollView
) asegura contentOffsetY >= 0
cuando el usuario intenta desplazarse haciendo un snap visible contentOffsetY = 0
. Esto parece 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 Matt
solución me parece correcta, debe tener en cuenta también la inserción de la vista de recopilación si hay una 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 vista de tabla:
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
el self.tableView
(iOS 4.1)
, después de añadir 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];
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 en contentSize
realidad no refleja el tamaño real del texto, por lo que cuando intente desplazarse hacia la parte inferior, estará un poco apagado. La mejor manera de determinar el tamaño real del contenido es usar el método de NSLayoutManager
s usedRectForTextContainer:
:
UITextView *textView;
CGSize textSize = [textView.layoutManager usedRectForTextContainer:textView.textContainer].size;
Para determinar cuánto texto se muestra realmente 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 de referencia sobre lo que representan los diferentes tamaños para un vacío UITextView
.
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)
Extienda UIScrollView para agregar un método scrollToBottom:
extension UIScrollView {
func scrollToBottom(animated:Bool) {
let offset = self.contentSize.height - self.visibleSize.height
if offset > self.contentOffset.y {
self.setContentOffset(CGPoint(x: 0, y: offset), animated: animated)
}
}
}
Versión Xamarin.iOSUICollectionView
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);