Come faccio a far scorrere verso l'alto un UIScrollView?
Come faccio a far scorrere verso l'alto un UIScrollView?
Risposte:
[self.scrollView setContentOffset:
CGPointMake(0, -self.scrollView.contentInset.top) animated:YES];
[self.scrollView setContentOffset:CGPointZero animated:YES];
o se si desidera preservare la posizione di scorrimento orizzontale e ripristinare la posizione verticale:
[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, 0)
animated:YES];
[scrollView setContentOffset:CGPointMake(0, -scrollView.contentInset.top) animated:YES];
Funziona su iOS 6 e 7
[scrollView setContentOffset:CGPointMake(0, scrollView.contentSize.height-scrollView.frame.size.height) animated:YES];
Ecco un'estensione Swift che semplifica:
extension UIScrollView {
func scrollToTop() {
let desiredOffset = CGPoint(x: 0, y: -contentInset.top)
setContentOffset(desiredOffset, animated: true)
}
}
Uso:
myScrollView.scrollToTop()
prova a lavorare con il nuovo adjustedContentInset
.
Ad esempio (scorrere verso l'alto):
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)
Anche se usi
prefersLargeTitles
,safe area
ecc.
Per Swift 4
scrollView.setContentOffset(.zero, animated: true)
Uso setContentOffset:animated:
[scrollView setContentOffset:CGPointZero animated:YES];
In iOS7 ho avuto difficoltà a ottenere una particolare vista di scorrimento per andare in cima, che ha funzionato in iOS6, e ho usato questo per impostare la vista di scorrimento per andare in cima.
[self.myScroller scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:NO];
Versione Swift 3.0.1 della risposta di rob mayoff :
self.scrollView.setContentOffset(
CGPoint(x: 0,y: -self.scrollView.contentInset.top),
animated: true)
Per replicare completamente il comportamento scrollToTop della barra di stato, non solo dobbiamo impostare contentOffset, ma vogliamo anche assicurarci che vengano visualizzati gli Indicatori di scorrimento. Altrimenti l'utente può perdersi rapidamente.
L'unico metodo pubblico per raggiungere questo obiettivo è flashScrollIndicators
. Sfortunatamente, chiamarlo una volta dopo aver impostato contentOffset non ha alcun effetto perché viene ripristinato immediatamente. Ho scoperto che funziona ogni volta che esegui il flash 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;
});
}
Nel tuo UIScrollViewDelegate (o UITable / UICollectionViewDelegate) implementa questo:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.tag == SCROLLVIEW_IS_SCROLLING_TO_TOP_TAG) {
[scrollView flashScrollIndicators];
}
}
Il ritardo di nascondere è un po 'più breve rispetto al comportamento scrollToTop della barra di stato, ma sembra comunque carino.
Si noti che sto abusando del tag di visualizzazione per comunicare lo stato "isScrollingToTop" perché ne ho bisogno attraverso i controller di visualizzazione. Se stai usando i tag per qualcos'altro, potresti volerlo sostituire con un iVar o una proprietà.
Penso di avere una risposta che dovrebbe essere pienamente compatibile con iOS 11 e versioni precedenti (per scorrimento verticale)
Ciò tiene conto del nuovo adjustedContentInset e tiene conto anche dell'offset aggiuntivo richiesto quando si preferisce LargeTitles è abilitato sulla navigazione, che sembra richiedere un offset extra di 52px sopra qualunque sia l'impostazione predefinita
Questo è stato un po 'complicato perché la regolazione di AdjustContentInset varia in base allo stato titleBar (titolo grande vs titolo piccolo), quindi ho dovuto controllare e vedere qual era l'altezza del titleBar e non applicare l'offset 52px se è già nello stato grande. Impossibile trovare altri metodi per controllare lo stato della barra di navigazione, quindi se qualcuno ha un'opzione migliore rispetto a vedere se l'altezza è> 44,0 mi piacerebbe ascoltarlo
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)
}
}
Ispirato dalla soluzione di Jakub
È molto comune quando la barra di navigazione si sovrappone alla piccola porzione del contenuto scrollView e sembra che il contenuto non inizi dall'alto. Per ripararlo ho fatto 2 cose:
Rotolo alla parte superiore per UITableViewController
, UICollectionViewController
o UIViewController
aventiUIScrollView
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 Basta impostare Content Offset su zero
scrollView.setContentOffset(CGPoint.zero, animated: true)
Ho provato in tutti i modi. Ma niente ha funzionato per me. Alla fine mi è piaciuto.
Ho aggiunto la self.view .addSubview(self.scroll)
riga di codice in viewDidLoad. Dopo aver iniziato a configurare la cornice per la vista di scorrimento e i componenti aggiunti alla vista di scorrimento.
Ha funzionato per me.
Assicurati di aver aggiunto la self.view .addSubview(self.scroll)
riga all'inizio. quindi è possibile aggiungere elementi dell'interfaccia utente.
UIScrollView
contentInset
, sfortunatamente.[self.scrollView setContentOffset:CGPointMake(self.scrollView.contentOffset.x, -self.scrollView.contentInset.top) animated:YES];
fa il lavoro per me