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.