Wie kann ich eine UIScrollView nach oben scrollen lassen?
Wie kann ich eine UIScrollView nach oben scrollen lassen?
Antworten:
[self.scrollView setContentOffset:
CGPointMake(0, -self.scrollView.contentInset.top) animated:YES];
[self.scrollView setContentOffset:CGPointZero animated:YES];
oder wenn Sie die horizontale Bildlaufposition beibehalten und einfach die vertikale Position zurücksetzen möchten:
[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, 0)
animated:YES];
[scrollView setContentOffset:CGPointMake(0, -scrollView.contentInset.top) animated:YES];
Es funktioniert in iOS 6 & 7
[scrollView setContentOffset:CGPointMake(0, scrollView.contentSize.height-scrollView.frame.size.height) animated:YES];
Hier ist eine Swift-Erweiterung, die es einfach macht:
extension UIScrollView {
func scrollToTop() {
let desiredOffset = CGPoint(x: 0, y: -contentInset.top)
setContentOffset(desiredOffset, animated: true)
}
}
Verwendung:
myScrollView.scrollToTop()
versuche mit dem neuen zu arbeiten adjustedContentInset
.
Zum Beispiel (nach oben scrollen):
var offset = CGPoint(
x: -scrollView.contentInset.left,
y: -scrollView.contentInset.top)
if #available(iOS 11.0, *) {
offset = CGPoint(
x: -scrollView.adjustedContentInset.left,
y: -scrollView.adjustedContentInset.top)
}
scrollView.setContentOffset(offset, animated: true)
Auch wenn Sie verwenden
prefersLargeTitles
,safe area
etc.
Für Swift 4
scrollView.setContentOffset(.zero, animated: true)
Verwenden setContentOffset:animated:
[scrollView setContentOffset:CGPointZero animated:YES];
In iOS7 hatte ich Probleme, eine bestimmte Bildlaufansicht nach oben zu bringen, was in iOS6 funktionierte, und habe damit die Bildlaufansicht so eingestellt, dass sie nach oben zeigt.
[self.myScroller scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
Swift 3.0.1 Version von Rob Mayoffs Antwort :
self.scrollView.setContentOffset(
CGPoint(x: 0,y: -self.scrollView.contentInset.top),
animated: true)
Um das scrollToTop-Verhalten der Statusleiste vollständig zu replizieren, müssen wir nicht nur das contentOffset festlegen, sondern auch sicherstellen, dass die scrollIndicators angezeigt werden. Andernfalls kann der Benutzer schnell verloren gehen.
Die einzige öffentliche Methode, um dies zu erreichen, ist flashScrollIndicators
. Leider hat das einmalige Aufrufen nach dem Festlegen von contentOffset keine Auswirkung, da es sofort zurückgesetzt wird. Ich fand, dass es funktioniert, wenn ich jedes Mal den Blitz mache scrollViewDidScroll:
.
// define arbitrary tag number in a global constants or in the .pch file
#define SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG 19291
- (void)scrollContentToTop {
[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.scrollView.contentInset.top) animated:YES];
self.scrollView.tag = SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.scrollView.tag = 0;
});
}
Implementieren Sie in Ihrem UIScrollViewDelegate (oder UITable / UICollectionViewDelegate) Folgendes:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.tag == SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG) {
[scrollView flashScrollIndicators];
}
}
Die Ausblendverzögerung ist etwas kürzer als das ScrollToTop-Verhalten in der Statusleiste, sieht aber trotzdem gut aus.
Beachten Sie, dass ich das Ansichtstag verwende, um den Status "isScrollingToTop" zu kommunizieren, da ich dies über Ansichtscontroller hinweg benötige. Wenn Sie Tags für etwas anderes verwenden, möchten Sie diese möglicherweise durch ein iVar oder eine Eigenschaft ersetzen.
Ich denke, ich habe eine Antwort, die sowohl mit iOS 11 als auch mit früheren Versionen (für vertikales Scrollen) vollständig kompatibel sein sollte.
Dies berücksichtigt das neue AdjustedContentInset und berücksichtigt auch den zusätzlichen Offset, der erforderlich ist, wenn PreferLargeTitles bevorzugt wird in der Navigationsleiste ist. scheint einen zusätzlichen Versatz von 52 Pixel zusätzlich zu den Standardeinstellungen zu erfordern
Dies war etwas knifflig, da sich das angepasste ContentInset abhängig vom titleBar-Status (großer Titel vs. kleiner Titel) ändert. Daher musste ich überprüfen, wie hoch die titleBar-Höhe war, und den 52px-Offset nicht anwenden, wenn er sich bereits im großen Status befindet. Es konnte keine andere Methode gefunden werden, um den Status der Navigationsleiste zu überprüfen. Wenn also jemand eine bessere Option hat, als zu sehen, ob die Höhe> 44,0 ist, würde ich sie gerne hören
func scrollToTop(_ scrollView: UIScrollView, animated: Bool = true) {
if #available(iOS 11.0, *) {
let expandedBar = (navigationController?.navigationBar.frame.height ?? 64.0 > 44.0)
let largeTitles = (navigationController?.navigationBar.prefersLargeTitles) ?? false
let offset: CGFloat = (largeTitles && !expandedBar) ? 52: 0
scrollView.setContentOffset(CGPoint(x: 0, y: -(scrollView.adjustedContentInset.top + offset)), animated: animated)
} else {
scrollView.setContentOffset(CGPoint(x: 0, y: -scrollView.contentInset.top), animated: animated)
}
}
Inspiriert von Jakubs Lösung
Es ist sehr häufig, wenn Ihre Navigationsleiste den kleinen Teil des scrollView-Inhalts überlappt und es so aussieht, als würde der Inhalt nicht von oben beginnen. Um das Problem zu beheben, habe ich zwei Dinge getan:
Nach oben scrollen für UITableViewController
, UICollectionViewController
oder jeder UIViewController
mitUIScrollView
extension UIViewController {
func scrollToTop(animated: Bool) {
if let tv = self as? UITableViewController {
tv.tableView.setContentOffset(CGPoint.zero, animated: animated)
} else if let cv = self as? UICollectionViewController{
cv.collectionView?.setContentOffset(CGPoint.zero, animated: animated)
} else {
for v in view.subviews {
if let sv = v as? UIScrollView {
sv.setContentOffset(CGPoint.zero, animated: animated)
}
}
}
}
}
In SWIFT 5 Setzen Sie einfach den Inhaltsversatz auf Null
scrollView.setContentOffset(CGPoint.zero, animated: true)
Ich habe alle Möglichkeiten ausprobiert. Aber nichts hat bei mir funktioniert. Endlich hat mir das gefallen.
Ich habe eine self.view .addSubview(self.scroll)
Codezeile in viewDidLoad hinzugefügt. Nach dem Einrichten des Rahmens für die Bildlaufansicht und dem Hinzufügen von Komponenten zur Bildlaufansicht.
Es hat bei mir funktioniert.
Stellen Sie sicher, dass Sie self.view .addSubview(self.scroll)
am Anfang eine Zeile hinzugefügt haben . Dann können Sie UI-Elemente hinzufügen.
UIScrollView
contentInset
leider berücksichtigen .[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.scrollView.contentInset.top) animated:YES];
macht den Job für mich