144 votes

Index de la cellule visible actuelle du UICollectionView

J'utilise UICollectionView pour la première fois dans mon application iPad. J'ai défini UICollectionView de sorte que sa taille et celle de la cellule soient identiques, ce qui signifie qu'une seule cellule est affichée à la fois.

Problème : Maintenant, lorsque l'utilisateur fait défiler UICollectionView J'ai besoin de savoir quelle cellule est visible. Je dois mettre à jour les autres éléments de l'interface utilisateur en cas de changement. Je n'ai pas trouvé de méthode déléguée pour cela. Comment puis-je réaliser cela ?

Code :

[self.mainImageCollection setTag:MAIN_IMAGE_COLLECTION_VIEW];
[self.mainImageCollection registerClass:[InspirationMainImageCollectionCell class] forCellWithReuseIdentifier:@"cellIdentifier"];
[self.mainImageFlowLayout setScrollDirection:UICollectionViewScrollDirectionHorizontal];
[self.mainImageFlowLayout setMinimumInteritemSpacing:0.0f];
[self.mainImageFlowLayout setMinimumLineSpacing:0.0f];
self.mainImageFlowLayout.minimumLineSpacing = 0;
[self.mainImageCollection setPagingEnabled:YES];
[self.mainImageCollection setShowsHorizontalScrollIndicator:NO];
[self.mainImageCollection setCollectionViewLayout:self.mainImageFlowLayout];

Ce que j'ai essayé :

Como UICollectionView est conforme à UIScrollView que j'obtiens lorsque le défilement de l'utilisateur se termine par UIScrollViewDelegate méthode

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView

Mais à l'intérieur de la fonction ci-dessus, comment puis-je obtenir l'index de la cellule visible actuelle de l'écran ? UICollectionView ?

226voto

Anthony Points 2073

indexPathsForVisibleItems peut fonctionner dans la plupart des cas, mais il arrive qu'elle renvoie un tableau comportant plus d'un chemin d'index et il peut être difficile de trouver celui que vous voulez. Dans ces situations, vous pouvez faire quelque chose comme ceci :

CGRect visibleRect = (CGRect){.origin = self.collectionView.contentOffset, .size = self.collectionView.bounds.size};
CGPoint visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect));
NSIndexPath *visibleIndexPath = [self.collectionView indexPathForItemAtPoint:visiblePoint];

Cela fonctionne particulièrement bien lorsque chaque élément de votre vue de collection occupe tout l'écran.

Version Swift

let visibleRect = CGRect(origin: collectionView.contentOffset, size: collectionView.bounds.size)
let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
let visibleIndexPath = collectionView.indexPathForItem(at: visiblePoint)

158voto

iAn Points 3599

La méthode [collectionView visibleCells] vous donne tous les tableaux visiblesCells que vous voulez. Utilisez-la lorsque vous voulez obtenir

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    for (UICollectionViewCell *cell in [self.mainImageCollection visibleCells]) {
        NSIndexPath *indexPath = [self.mainImageCollection indexPathForCell:cell];
        NSLog(@"%@",indexPath);
    }
}

Mise à jour vers Swift 5 :

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    for cell in yourCollectionView.visibleCells {
        let indexPath = yourCollectionView.indexPath(for: cell)
        print(indexPath)
    }
}

105voto

Sam Bing Points 1224

Swift 5 :

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
    var visibleRect = CGRect()

    visibleRect.origin = collectionView.contentOffset
    visibleRect.size = collectionView.bounds.size

    let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)

    guard let indexPath = collectionView.indexPathForItem(at: visiblePoint) else { return } 

    print(indexPath)
}

Réponses de travail combinées dans Swift 2.2 :

 func scrollViewDidEndDecelerating(scrollView: UIScrollView) {

        var visibleRect = CGRect()

        visibleRect.origin = self.collectionView.contentOffset
        visibleRect.size = self.collectionView.bounds.size

        let visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect))

        let visibleIndexPath: NSIndexPath = self.collectionView.indexPathForItemAtPoint(visiblePoint)

        guard let indexPath = visibleIndexPath else { return } 
        print(indexPath)

    }

20voto

Vincil Bishop Points 121

Pour être complet, voici la méthode qui a fini par fonctionner pour moi. C'est une combinaison des méthodes de @Anthony et @iAn.

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
      CGRect visibleRect = (CGRect){.origin = self.collectionView.contentOffset, .size = self.collectionView.bounds.size};
      CGPoint visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect));
      NSIndexPath *visibleIndexPath = [self.collectionView indexPathForItemAtPoint:visiblePoint];
      NSLog(@"%@",visibleIndexPath);
}

15voto

Mihail Salari Points 662

Index de la cellule visible actuelle du UICollectionView : Swift 3, 4 et 5+

var visibleCurrentCellIndexPath: IndexPath? {
    for cell in self.collectionView.visibleCells {
        let indexPath = self.collectionView.indexPath(for: cell)
        return indexPath
     }

     return nil
}

En tant qu'extension :

extension UICollectionView {
  var visibleCurrentCellIndexPath: IndexPath? {
    for cell in self.visibleCells {
      let indexPath = self.indexPath(for: cell)
      return indexPath
    }

    return nil
  }
}

Utilisation :

if let indexPath = collectionView.visibleCurrentCellIndexPath { 
   /// do something
}

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