web-dev-qa-db-fra.com

Obtenir la page actuelle

Dans ma vue par défilement, je souhaite obtenir la page actuelle qui est affichée (peut-être que page n'est pas le terme correct). Je ne peux trouver aucune variable qui tient ceci. Mais je pense que cela doit être maintenu quelque part, car l'indicateur est capable de montrer quelle vue secondaire de la vue par défilement est actuellement affichée.

Est-ce que cela nous est complètement caché ou y a-t-il un moyen pour moi d'y accéder?

92
user440096

Il n'y a pas de propriété UIScrollView pour la page en cours. Vous pouvez le calculer avec:

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

Si vous voulez arrondir à la page la plus proche, utilisez:

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

Je vous recommande plutôt d'utiliser ce code 

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

mais si vous utilisez ce code, votre vue n'a pas besoin d'être exactement sur la page que l'indexOfPage vous donne . C'est parce que je vous recommande également d'utiliser ce code uniquement dans cette méthode 

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

qui est appelé lorsque votre scrollView termine le défilement et que le numéro de votre page est vraiment net

Je vous recommande de régler votre scrollView sur paginé activé avec ce code

[scrollView setPagingEnabled:YES];

Donc finalement ça devrait ressembler à ça

-(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
}
29
Jiří Zahálka

Dans Swift je le ferais en extension:

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

Alors appelez juste:

scrollView.currentPage
27

Comme ci-dessus mais en tant que catégorie


@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
12
user363349

Il y a quelques bonnes réponses ici déjà. Toutefois, pour les scénarios dans lesquels le contenu ne s’intègre pas exactement dans une page - et si comme moi vous souhaitez utiliser le résultat pour un UIPageControl, il est essentiel d’utiliser la fonction ceil.

Prenons un exemple où j'ai des pages de contenu "quatre et un peu". 

Je vais me baser sur mon exemple réel actuel. La largeur de la taille du contenu est de 3140 points. Selon la taille du cadre de ma vue de collection, la largeur de la page est de 728.

Donc, le nombre de pages est égal à:

 3140 / 728 = 4.313 

Mon numberOfPages va être cinq. Quatre d'entre elles s'afficheront dans leur intégralité et la dernière - page cinq - indiquera le 0.313 restant du contenu.

Maintenant, numberOfPages étant cinq signifie que les index de page seront 0, 1, 2, 3 et 4. 

Lorsque je balaie vers la droite, en paginant vers le décalage final, la méthode scrollViewDidEndDecelerating donne un décalage X final de 2412.

Appliquer le calcul d'arrondi:

2412 / 728 = 3.313 then rounded = 3

C'est faux. L'utilisateur visualisé par offset devrait être:

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

Le calcul correct en utilisant 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
}
6
Max MacLeod

Il suffit de diviser le décalage actuel par la taille de la page:

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

Autrement :

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

Dans xCode 7.x Swift 2.x, vous pouvez effectuer les opérations suivantes:

//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
Alessandro Ornano

La solution de Aoakenfo est incroyable, c'est une autre solution combinant votre code avec la fonction scrollViewDidScroll et 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;
    }
}
3
pabloverd

Je l'ai extrait de quelques-unes de nos applications ...

- (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;
}

Source complète ici

2
Barry

Pour Swift, je voudrais simplement utiliser ceci 

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

Plutôt simple, il prend la position x scrollview, le divise par la largeur, puis l’arrondit.

2
Jackson U

Utilisez-vous un UIPageControl? Si c'est le cas, cela a une propriété currentPage. Sinon, je pense que vous devrez calculer l'index de page à partir du décalage scrollView.

1
wvteijlingen

Si quelqu'un cherche un moyen de faire en C # pour 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);
    }

Ce getter et Setter devrait vous fournir la page actuelle et vous permettre de faire défiler jusqu'à la page spécifiée.

0
soan saini