Réponses:
Vous pouvez utiliser la setContentOffset:animated:
fonction UIScrollView pour faire défiler jusqu'à n'importe quelle partie de la vue de contenu. Voici un code qui défilerait vers le bas, en supposant que votre scrollView est 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];
J'espère que cela pourra aider!
CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.contentInset.bottom);
contentSize
est inférieur à bounds
. Il devrait donc en être ainsi: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)
Version rapide de la réponse acceptée pour un copier-coller facile:
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height)
scrollView.setContentOffset(bottomOffset, animated: true)
Solution la plus simple:
[scrollview scrollRectToVisible:CGRectMake(scrollview.contentSize.width - 1,scrollview.contentSize.height - 1, 1, 1) animated:YES];
Juste une amélioration de la réponse existante.
CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.contentInset.bottom);
[self.scrollView setContentOffset:bottomOffset animated:YES];
Il prend également en charge l'encart inférieur (au cas où vous l'utiliseriez pour ajuster votre vue de défilement lorsque le clavier est visible)
Une implémentation rapide:
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)
}
}
utilise le:
yourScrollview.scrollToBottom(animated: true)
La définition du décalage du contenu à la hauteur de la taille du contenu est incorrecte: il fait défiler le bas du contenu vers le haut de la vue de défilement, et donc hors de vue.
La bonne solution consiste à faire défiler le bas du contenu vers le bas de la vue de défilement, comme ceci ( sv
est le 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:
commande qui est importante.
Une solution Swift 2.2, prenant contentInset
en compte
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom)
scrollView.setContentOffset(bottomOffset, animated: true)
Cela devrait être dans une extension
extension UIScrollView {
func scrollToBottom() {
let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height + contentInset.bottom)
setContentOffset(bottomOffset, animated: true)
}
}
Notez que vous voudrez peut-être vérifier si bottomOffset.y > 0
avant de faire défiler
Et si contentSize
est inférieur àbounds
?
Pour Swift, c'est:
scrollView.setContentOffset(CGPointMake(0, max(scrollView.contentSize.height - scrollView.bounds.size.height, 0) ), animated: true)
Faire défiler vers le haut
- CGPoint topOffset = CGPointMake(0, 0);
- [scrollView setContentOffset:topOffset animated:YES];
Faire défiler vers le bas
- CGPoint bottomOffset = CGPointMake(0, scrollView.contentSize.height - self.scrollView.bounds.size.height);
- [scrollView setContentOffset:bottomOffset animated:YES];
J'ai également trouvé un autre moyen utile de le faire dans le cas où vous utilisez un UITableview (qui est une sous-classe de UIScrollView):
[(UITableView *)self.view scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
Utilisation de la setContentOffset:animated:
fonction UIScrollView pour faire défiler vers le bas dans Swift.
let bottomOffset : CGPoint = CGPointMake(0, scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom)
scrollView.setContentOffset(bottomOffset, animated: true)
Il semble que toutes les réponses ici n'aient pas pris en compte la zone de sécurité. Depuis iOS 11, l'iPhone X a introduit une zone de sécurité. Cela peut affecter les scrollView contentInset
.
Pour iOS 11 et supérieur, pour faire défiler correctement vers le bas avec l'encart de contenu inclus. Vous devez utiliser à la adjustedContentInset
place de contentInset
. Vérifiez ce code:
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)
}
}
Références:
Rapide:
Vous pouvez utiliser une extension comme celle-ci:
extension UIScrollView {
func scrollsToBottom(animated: Bool) {
let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height)
setContentOffset(bottomOffset, animated: animated)
}
}
Utilisation:
scrollView.scrollsToBottom(animated: true)
Catégorie à la rescousse!
Ajoutez ceci à un en-tête d'utilitaire partagé quelque part:
@interface UIScrollView (ScrollToBottom)
- (void)scrollToBottomAnimated:(BOOL)animated;
@end
Et puis à cette implémentation de l'utilitaire:
@implementation UIScrollView(ScrollToBottom)
- (void)scrollToBottomAnimated:(BOOL)animated
{
CGPoint bottomOffset = CGPointMake(0, self.contentSize.height - self.bounds.size.height);
[self setContentOffset:bottomOffset animated:animated];
}
@end
Ensuite, implémentez-le où vous voulez, par exemple:
[[myWebView scrollView] scrollToBottomAnimated:YES];
Pour ScrollView horizontal
Si vous m'aimez a un ScrollView horizontal et que vous souhaitez faire défiler jusqu'à la fin (dans mon cas à l'extrême droite), vous devez modifier certaines parties de la réponse acceptée:
Objectif c
CGPoint rightOffset = CGPointMake(self.scrollView.contentSize.width - self.scrollView.bounds.size.width + self.scrollView.contentInset.right, 0 );
[self.scrollView setContentOffset:rightOffset animated:YES];
Rapide
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 vous changez en quelque sorte scrollView contentSize (par exemple, ajoutez quelque chose à stackView qui se trouve à l'intérieur de scrollView), vous devez appelerscrollView.layoutIfNeeded()
avant de faire défiler, sinon cela ne fait rien.
Exemple:
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)
}
Un bon moyen de s'assurer que le bas de votre contenu est visible est d'utiliser la formule:
contentOffsetY = MIN(0, contentHeight - boundsHeight)
Cela garantit que le bord inférieur de votre contenu est toujours au niveau ou au-dessus du bord inférieur de la vue. Le MIN(0, ...)
est requis car UITableView
(et probablement UIScrollView
) garantit contentOffsetY >= 0
que l'utilisateur essaie de faire défiler en claquant visiblementcontentOffsetY = 0
. Cela semble assez étrange pour l'utilisateur.
Le code pour implémenter ceci est:
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 vous n'avez pas besoin d'animation, cela fonctionne:
[self.scrollView setContentOffset:CGPointMake(0, CGFLOAT_MAX) animated:NO];
Bien que la Matt
solution me semble correcte, vous devez également prendre en compte l'encart de la vue de collection s'il y en a un qui a été configuré.
Le code adapté sera:
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];
}
Solution pour faire défiler jusqu'au dernier élément d'une table Voir:
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)
}
N'a pas travaillé pour moi, quand j'ai essayé de l' utiliser dans UITableViewController
le self.tableView
(iOS 4.1)
, après avoir ajoutéfooterView
. Il défile hors des frontières, montrant un écran noir.
Solution alternative:
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];
J'ai trouvé que contentSize
cela ne reflète pas vraiment la taille réelle du texte, donc lorsque vous essayez de faire défiler vers le bas, il sera un peu éteint. La meilleure façon de déterminer la taille du contenu réel est en fait d'utiliser la NSLayoutManager
de » usedRectForTextContainer:
méthode:
UITextView *textView;
CGSize textSize = [textView.layoutManager usedRectForTextContainer:textView.textContainer].size;
Pour déterminer la quantité de texte réellement affichée dans le UITextView
, vous pouvez le calculer en soustrayant les encarts du conteneur de texte de la hauteur du cadre.
UITextView *textView;
UIEdgeInsets textInsets = textView.textContainerInset;
CGFloat textViewHeight = textView.frame.size.height - textInsets.top - textInsets.bottom;
Ensuite, il devient facile de faire défiler:
// 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;
Quelques chiffres pour référence sur ce que les différentes tailles représentent pour un vide 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)
Étendez UIScrollView pour ajouter une méthode 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)
}
}
}
Version Xamarin.iOS pour UICollectionView
la réponse acceptée pour faciliter le copier-coller
var bottomOffset = new CGPoint (0, CollectionView.ContentSize.Height - CollectionView.Frame.Size.Height + CollectionView.ContentInset.Bottom);
CollectionView.SetContentOffset (bottomOffset, false);