Antworten:
Mit der setContentOffset:animated:
Funktion von UIScrollView können Sie zu einem beliebigen Teil der Inhaltsansicht blättern. Hier ist ein Code, der nach unten scrollen würde, vorausgesetzt, Ihre scrollView lautet 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];
Ich hoffe, das hilft!
CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.contentInset.bottom);
contentSize
es niedriger als ist bounds
. So sollte es sein: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)
Schnelle Version der akzeptierten Antwort zum einfachen Einfügen von Kopien:
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height)
scrollView.setContentOffset(bottomOffset, animated: true)
Einfachste Lösung:
[scrollview scrollRectToVisible:CGRectMake(scrollview.contentSize.width - 1,scrollview.contentSize.height - 1, 1, 1) animated:YES];
Nur eine Erweiterung der bestehenden Antwort.
CGPoint bottomOffset = CGPointMake(0, self.scrollView.contentSize.height - self.scrollView.bounds.size.height + self.scrollView.contentInset.bottom);
[self.scrollView setContentOffset:bottomOffset animated:YES];
Es kümmert sich auch um den unteren Einschub (falls Sie diesen verwenden, um Ihre Bildlaufansicht anzupassen, wenn die Tastatur sichtbar ist)
Das Einstellen des Inhaltsversatzes auf die Höhe der Inhaltsgröße ist falsch: Es wird der untere Rand des Inhalts nach oben verschoben der Bildlaufansicht und ist somit nicht sichtbar.
Die richtige Lösung besteht darin, den unteren Rand des Inhalts wie folgt zum unteren Randsv
der Bildlaufansicht zu scrollen ( ist die 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:
Befehl, der wichtig ist.
Eine schnelle Implementierung:
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)
}
}
benutze es:
yourScrollview.scrollToBottom(animated: true)
Eine Swift 2.2-Lösung unter contentInset
Berücksichtigung
let bottomOffset = CGPoint(x: 0, y: scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom)
scrollView.setContentOffset(bottomOffset, animated: true)
Dies sollte in einer Erweiterung sein
extension UIScrollView {
func scrollToBottom() {
let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height + contentInset.bottom)
setContentOffset(bottomOffset, animated: true)
}
}
Beachten Sie, dass Sie bottomOffset.y > 0
vor dem Scrollen überprüfen möchten, ob
Was ist, wenn contentSize
niedriger als ist bounds
?
Für Swift ist es:
scrollView.setContentOffset(CGPointMake(0, max(scrollView.contentSize.height - scrollView.bounds.size.height, 0) ), animated: true)
Scrolle nach oben
- CGPoint topOffset = CGPointMake(0, 0);
- [scrollView setContentOffset:topOffset animated:YES];
Scrollen Sie nach unten
- CGPoint bottomOffset = CGPointMake(0, scrollView.contentSize.height - self.scrollView.bounds.size.height);
- [scrollView setContentOffset:bottomOffset animated:YES];
Ich habe auch einen anderen nützlichen Weg gefunden, dies zu tun, wenn Sie eine UITableview verwenden (eine Unterklasse von UIScrollView):
[(UITableView *)self.view scrollToRowAtIndexPath:scrollIndexPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
Verwenden der UIScrollView- setContentOffset:animated:
Funktion, um in Swift nach unten zu scrollen.
let bottomOffset : CGPoint = CGPointMake(0, scrollView.contentSize.height - scrollView.bounds.size.height + scrollView.contentInset.bottom)
scrollView.setContentOffset(bottomOffset, animated: true)
Es sieht so aus, als hätten alle Antworten hier den sicheren Bereich nicht berücksichtigt. Seit iOS 11 wurde auf dem iPhone X ein sicherer Bereich eingeführt. Dies kann sich auf die scrollView auswirken contentInset
.
Scrollen Sie für iOS 11 und höher mit dem enthaltenen Inhaltseinsatz ordnungsgemäß nach unten. Sie sollten adjustedContentInset
anstelle von verwenden contentInset
. Überprüfen Sie diesen 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)
}
}
Verweise:
Schnell:
Sie könnten eine Erweiterung wie diese verwenden:
extension UIScrollView {
func scrollsToBottom(animated: Bool) {
let bottomOffset = CGPoint(x: 0, y: contentSize.height - bounds.size.height)
setContentOffset(bottomOffset, animated: animated)
}
}
Verwenden:
scrollView.scrollsToBottom(animated: true)
Kategorie zur Rettung!
Fügen Sie dies irgendwo zu einem gemeinsam genutzten Dienstprogramm-Header hinzu:
@interface UIScrollView (ScrollToBottom)
- (void)scrollToBottomAnimated:(BOOL)animated;
@end
Und dann zu dieser Dienstprogrammimplementierung:
@implementation UIScrollView(ScrollToBottom)
- (void)scrollToBottomAnimated:(BOOL)animated
{
CGPoint bottomOffset = CGPointMake(0, self.contentSize.height - self.bounds.size.height);
[self setContentOffset:bottomOffset animated:animated];
}
@end
Implementieren Sie es dann, wo immer Sie möchten, zum Beispiel:
[[myWebView scrollView] scrollToBottomAnimated:YES];
Für horizontale ScrollView
Wenn Sie möchten, dass ich eine horizontale Bildlaufansicht habe und zum Ende scrollen möchte (in meinem Fall ganz rechts davon), müssen Sie einige Teile der akzeptierten Antwort ändern:
Ziel c
CGPoint rightOffset = CGPointMake(self.scrollView.contentSize.width - self.scrollView.bounds.size.width + self.scrollView.contentInset.right, 0 );
[self.scrollView setContentOffset:rightOffset animated:YES];
Schnell
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)
Wenn Sie scrollView contentSize irgendwie ändern (z. B. etwas zu stackView hinzufügen, das sich in scrollView befindet), müssen Sie aufrufenscrollView.layoutIfNeeded()
vor dem Scrollen , da dies sonst nichts bewirkt.
Beispiel:
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)
}
Eine gute Möglichkeit, um sicherzustellen, dass der untere Teil Ihres Inhalts sichtbar ist, ist die Verwendung der folgenden Formel:
contentOffsetY = MIN(0, contentHeight - boundsHeight)
Dadurch wird sichergestellt, dass sich der untere Rand Ihres Inhalts immer am oder über dem unteren Rand der Ansicht befindet. Dies MIN(0, ...)
ist erforderlich, weil UITableView
(und wahrscheinlich UIScrollView
) sichergestellt wird, contentOffsetY >= 0
wenn der Benutzer versucht, durch sichtbares Einrasten einen Bildlauf durchzuführencontentOffsetY = 0
. Das sieht für den Benutzer ziemlich seltsam aus.
Der Code, um dies zu implementieren, lautet:
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];
}
Wenn Sie keine Animation benötigen, funktioniert dies:
[self.scrollView setContentOffset:CGPointMake(0, CGFLOAT_MAX) animated:NO];
Während Matt
mir die Lösung richtig erscheint, müssen Sie auch die eingefügte Sammlungsansicht berücksichtigen, wenn eine eingerichtet wurde.
Der angepasste Code lautet:
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];
}
Lösung zum Scrollen zum letzten Element einer Tabelle Ansicht:
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)
}
Haben Sie nicht für mich arbeiten, als ich versuchte , es zu benutzen , in UITableViewController
auf self.tableView
(iOS 4.1)
, nach dem HinzufügenfooterView
. Es rollt aus den Rändern heraus und zeigt einen schwarzen Bildschirm.
Alternative Lösung:
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];
Ich habe festgestellt, dass contentSize
dies nicht wirklich die tatsächliche Größe des Textes widerspiegelt. Wenn Sie also versuchen, nach unten zu scrollen, wird es ein wenig abweichen. Der beste Weg , die tatsächlichen Inhalt Größe zu bestimmen , ist tatsächlich die verwenden NSLayoutManager
‚s - usedRectForTextContainer:
Methode:
UITextView *textView;
CGSize textSize = [textView.layoutManager usedRectForTextContainer:textView.textContainer].size;
Um festzustellen, wie viel Text tatsächlich in der angezeigt wird UITextView
, können Sie ihn berechnen, indem Sie die Textcontainer-Einfügungen von der Rahmenhöhe abziehen.
UITextView *textView;
UIEdgeInsets textInsets = textView.textContainerInset;
CGFloat textViewHeight = textView.frame.size.height - textInsets.top - textInsets.bottom;
Dann wird es einfach zu scrollen:
// 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;
Einige Zahlen als Referenz dafür, was die verschiedenen Größen für ein leeres darstellen 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)
Erweitern Sie UIScrollView, um eine scrollToBottom-Methode hinzuzufügen:
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)
}
}
}
Xamarin.iOS- Version für UICollectionView
die akzeptierte Antwort zum einfachen Kopieren und Einfügen
var bottomOffset = new CGPoint (0, CollectionView.ContentSize.Height - CollectionView.Frame.Size.Height + CollectionView.ContentInset.Bottom);
CollectionView.SetContentOffset (bottomOffset, false);