Ottenere la pagina corrente


97

Nella mia visualizzazione a scorrimento, voglio ottenere la pagina corrente che viene visualizzata (forse la pagina non è il termine corretto). Non riesco a trovare nessuna variabile che lo contenga. Ma penso che debba essere tenuto da qualche parte, poiché l'indicatore è in grado di mostrare quale sotto-visualizzazione della visualizzazione a scorrimento è attualmente visualizzata.

Questo ci è completamente nascosto o c'è un modo per accedervi?

Risposte:


263

Nessuna UIScrollViewproprietà per la pagina corrente. Puoi calcolarlo con:

int page = scrollView.contentOffset.x / scrollView.frame.size.width;

Se vuoi arrotondare per eccesso o per difetto alla pagina più vicina, usa:

CGFloat width = scrollView.frame.size.width;
NSInteger page = (scrollView.contentOffset.x + (0.5f * width)) / width;

7
Non dimenticare di utilizzare UIScrollViewDelegateper ottenere la pagina corrente quando l'utente scorre!
Sam Spencer

Questo potrebbe avere problemi quando si tratta di rotazione.
Jason McCreary

si prega di aggiungere la versione rapida
fnc12

1
Non sempre funziona, a volte la larghezza della cornice è sbagliata.
Rodrigo Ruiz

Questo non funziona sempre. A volte ottengo la pagina come 0 che è sbagliato nel mio caso.
Sneha

32

Ti consiglio piuttosto di usare questo codice

int indexOfPage = scrollView.contentOffset.x / scrollView.frame.size.width;

ma se usi questo codice la tua vista non deve essere esattamente sulla pagina che ti fornisce indexOfPage. È perché ti consiglio anche di usare questo codice solo in questo metodo

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{}

che viene chiamato quando il tuo scrollView finisce di scorrere e per avere il numero della tua pagina veramente nitido

Ti consiglio di impostare il tuo scrollView su paged abilitato con questo codice

[scrollView setPagingEnabled:YES];

Quindi alla fine dovrebbe apparire così

-(void) methodWhereYouSetYourScrollView
{
   //set scrollView
   [scrollView setPagingEnabled:YES];
   scrollView.delegate = self;
}

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
   int indexOfPage = scrollView.contentOffset.x / scrollView.frame.size.width;
   //your stuff with index
}

non funziona sul dispositivo iOS7 (compilato con XCODE 6.2) contentOffset.x è uguale a 639 invece di 640 (non chiedermi perché ...) quando scrollViewDidEndDecelerating. user363349 la risposta è corretta: return floor ((self.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
Vassily

Questo non funziona sempre. A volte ottengo la pagina come 0 che è sbagliato nel mio caso.
Sneha

30

In swift lo farei in estensione:

extension UIScrollView {
    var currentPage:Int{
        return Int((self.contentOffset.x+(0.5*self.frame.size.width))/self.frame.width)+1
    }
}

Quindi chiama semplicemente:

scrollView.currentPage

10
Quasi perfetto, ho dovuto rimuovere il +1 alla fine poiché tutto è basato su zero nel mio mondo
mvandillen

12

Come sopra ma come categoria


@interface UIScrollView (CurrentPage)
-(int) currentPage;
@end
@implementation UIScrollView (CurrentPage)
-(int) currentPage{
    CGFloat pageWidth = self.frame.size.width;
    return floor((self.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
}
@end

6
È esagerato, basta usare return round (self.contentOffset.x / self.frame.size.width); Molto più semplice e più facile da capire ..
Leonard Pauli

-1 @LeonardPauli. L'implementazione precedente restituisce la pagina che è visibile per oltre il 50%. L'implementazione ingenua cambia il valore della pagina solo quando la sottoview della scrollview occupa tutti i limiti della scrollview.
utente

1
@user In primo luogo, floor () arrotonda sempre per difetto e round () arrotonda per eccesso se la parte decimale è> = 5, altrimenti per difetto. Detto questo, floor (a) = round (a-0.5). Facciamo un po 'di algebra semplice. piano ((ab / 2) / b) +1 = piano (a / b-0,5) +1 = giro (a / b-0,5-0,5) +1 = giro (a / b-1) +1 = giro ( a / b). Guarda! Sembra che floor ((ab / 2) / b) +1 = round (a / b)! Mathemagical.
Leonard Pauli

Ma sì, se per qualche motivo avessi usato il pavimento invece, allora avresti perfettamente ragione! ;)
Leonard Pauli

8

Un altro modo :

extension MyViewController: UIScrollViewDelegate {
    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        let width = scrollView.frame.width
        let page = Int(round(scrollView.contentOffset.x/width))
        print("CurrentPage:\(page)")
    }
}

6

Basta dividere l'offset corrente per le dimensioni della pagina:

CGFloat pageNum = (int)(scrollView.contentOffset.x / scrollView.frame.size.width);

11
Casting a int e quindi assegnazione a un float? Perché non creare anche pageNum int;)
Klaas

6

Ci sono già alcune buone risposte qui. Tuttavia, per gli scenari in cui il contenuto non si adatta esattamente a una pagina e se, come me, desideri utilizzare il risultato per un UIPageControl, è essenziale utilizzare ilceil funzione.

Facciamo un esempio in cui ho "quattro e un po '" pagine di contenuto.

Baserò questo sul mio attuale esempio di vita reale. La larghezza della dimensione del contenuto è 3140 punti. In base alle dimensioni del frame della vista della raccolta, la larghezza della pagina è 728.

Quindi il numero di pagine è uguale a:

 3140 / 728 = 4.313 

Il mio numberOfPagessara 'cinque. Quattro dei quali verranno visualizzati per intero, e l'ultimo dei quali - pagina cinque - mostrerà il 0.313contenuto rimanente .

Ora, numberOfPagesessere cinque significa che gli indici di pagina saranno 0, 1, 2, 3 e 4.

Quando scorro verso destra, sfogliando verso l'offset finale, il file scrollViewDidEndDecelerating metodo fornisce un offset X finale di 2412.

Applicazione del calcolo dell'arrotondamento:

2412 / 728 = 3.313 then rounded = 3

Non è corretto. La pagina che l'utente sta visualizzando per offset dovrebbe essere:

Offset / Page User Is Viewing
0        0
728      1
1456     2
2184     3
2412     4

Il calcolo corretto utilizzando ceil:

private func pageForOffset(offset:CGFloat, pageWidth width:CGFloat) -> Int
{
    let page = Int(ceil(offset / width))
    NSLog("\(__FUNCTION__) offset \(offset) width \(width) page \(page) ")
    return page
}

4

Per swift vorrei solo usare questo

    let width = scrollView.frame.width
    let page = round(scrollView.contentOffset.x/width)

Abbastanza semplice, fondamentalmente prende la posizione x di scrollview, la divide per la larghezza di scrollview, quindi la arrotonda.


3

In xCode 7.x swift 2.x puoi fare:

//MARK: - ScrollView Extensions
// Get the current page number
extension UIScrollView {
    var currentPage: Int {
        return Int(round(self.contentOffset.x / self.bounds.size.width))
    }

// If you have reversed offset (start from contentSize.width to 0)
    var reverseCurrentPage: Int {
        return Int(round((contentSize.width - self.contentOffset.x) / self.bounds.size.width))-1
    }
}

3

La soluzione di Aoakenfo è sorprendente, questa è un'altra soluzione che combina il tuo codice con la funzione scrollViewDidScroll e PageController

- (void)scrollViewDidScroll:(UIScrollView *)sender {
    if (sender == self.scroll) {
        int pageNum = (int)(self.scrPage.contentOffset.x / self.scrPage.frame.size.width);
        self.pagecontroller.currentPage =pageNum;
    }
}

1
Questo è avido, non pigro ... Inoltre non è MVC. Un modo molto più semplice è invalidare la pagina corrente durante lo scorrimento e impostarla solo quando è richiesta ... tutto da una sottoclasse o categoria su UIScrollView

2

L'ho estratto da un paio delle nostre app ...

- (NSInteger)currentPage
{
    if (0 == self.frame.size.width) {
        NSLog(@"frame width == 0!");
        return 0;
    }
    if (! self.currentPageValid) {
        _currentPage = round(self.contentOffset.x / self.frame.size.width);
        self.currentPageValid = YES;
    }
    return _currentPage;
}

Fonte completa qui


1

Stai usando un UIPageControl? Se è così, questo ha una currentPageproprietà. In caso contrario, penso che dovrai calcolare l'indice della pagina dall'offset scrollView.


0

If Any one Looking for way of do in C # for Xamarin

    public int CurrentIndex
    {
        get => (int)Math.Round(this.scrollView.ContentOffset.X / this.scrollView.Frame.Width);
        set => this.scrollView.ScrollRectToVisible(new CGRect(new CGPoint(this.scrollView.Frame.Size.Width * value, 0), this.scrollView.Frame.Size), true);
    }

Questo getter e setter dovrebbero fornirti anche la pagina corrente e consentirti di scorrere fino alla pagina specificata


0

Estensione UIScrollView Swift 5.1+ (omissione della parola chiave return)

extension UIScrollView {

    var currentPage: Int {
        Int(round(self.contentOffset.x / self.frame.width))
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.