100 votes

Récupérer la page en cours

Dans ma vue défilante, je veux obtenir la page en cours d'affichage (peut-être que page n'est pas le terme correct). Je n'arrive pas à trouver une variable qui contienne cela. Mais je pense qu'elle doit être contenue quelque part, puisque l'indicateur est capable de montrer quelle sous-vue de la vue défilante 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 ?

268voto

AlexVogel Points 4574

Il n'y a pas UIScrollView de la page en cours. Vous pouvez la calculer avec :

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

Si vous voulez arrondir à la page supérieure ou inférieure la plus proche, utilisez :

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

7 votes

N'oubliez pas d'utiliser le UIScrollViewDelegate pour obtenir la page actuelle lorsque l'utilisateur fait défiler la page !

0 votes

Cela peut poser des problèmes en cas de rotation.

0 votes

Veuillez ajouter la version swift

33voto

Jiří Zahálka Points 32

Je vous recommande vivement 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 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 pour que le numéro de votre page soit vraiment net.

Je vous recommande de configurer votre scrollView pour qu'il soit activé en mode pagination 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
}

0 votes

Ne fonctionne pas sur un appareil iOS7 (compilé avec XCODE 6.2) contentOffset.x est égal à 639 au lieu de 640 (ne me demandez pas pourquoi...) lorsque scrollViewDidEndDecelerating. user363349 la réponse est correcte : return floor((self.contentOffset.x - pageWidth / 2) / pageWidth) + 1 ;

0 votes

Cela ne fonctionne pas toujours. Parfois, j'obtiens la page 0, ce qui est faux dans mon cas.

12voto

user363349 Points 762

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

7 votes

C'est exagéré, utilisez simplement return round(self.contentOffset.x / self.frame.size.width) ; Beaucoup plus simple et facile à comprendre

0 votes

-1 @LeonardPauli. L'implémentation ci-dessus renvoie la page qui est visible à plus de 50%. L'implémentation naïve ne change la valeur de la page que lorsque la sous-vue du scrollview occupe la totalité des limites du scrollview.

1 votes

@user Tout d'abord, floor() arrondit toujours vers le bas, et round() arrondit vers le haut si la partie décimale est >= 5, sinon vers le bas. Ceci étant dit, floor(a)=round(a-0.5). Faisons un peu d'algèbre simple. floor((a-b/2)/b)+1 = floor(a/b-0.5)+1 = round(a/b-0.5-0.5)+1 = round(a/b-1)+1 = round(a/b). Regardez ! Il semble que le plancher((a-b/2)/b)+1 = rond(a/b) ! Mathémagique.

6voto

aoakenfo Points 228

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

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

11 votes

Transformation en int et ensuite assignation à un float ? Pourquoi ne pas faire de pageNum un int également ;)

4voto

pabloverd Points 219

La solution d'Aoakenfo est étonnante, voici 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;
    }
}

1 votes

C'est de l'avidité, pas de la paresse... Ce n'est pas non plus MVC. Une manière beaucoup plus simple est d'invalider la page courante lors du défilement, et de la définir uniquement lorsqu'elle est demandée... le tout à partir d'une sous-classe ou d'une catégorie de UIScrollView.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X