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?
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;
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
}
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
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
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
}
Il suffit de diviser le décalage actuel par la taille de la page:
CGFloat pageNum = (int)(scrollView.contentOffset.x / scrollView.frame.size.width);
Autrement :
extension MyViewController: UIScrollViewDelegate {
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let width = scrollView.frame.width
let page = Int(round(scrollView.contentOffset.x/width))
print("CurrentPage:\(page)")
}
}
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
}
}
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;
}
}
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;
}
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.
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.
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.