web-dev-qa-db-fra.com

UICollectionView index de cellules visibles en cours

J'utilise UICollectionView pour la première fois dans mon application iPad . J'ai défini UICollectionView de sorte que sa taille et sa taille de 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 d'autres éléments de l'interface utilisateur à la modification. Je n'ai trouvé aucune méthode de délégué pour cela. Comment puis-je atteindre cet objectif?

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é:

Comme UICollectionView Conforme à UIScrollView, j'ai obtenu lorsque l'utilisateur scroll se termine avec la méthode UIScrollViewDelegate

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView

Mais à l'intérieur de la fonction ci-dessus, comment puis-je obtenir l'index de cellules visibles actuel de UICollectionView ???

87
Irfan DANISH

La méthode [collectionView visibleCells] vous donne tout le tableau visibleCells que vous voulez. Utilisez-le quand vous voulez obtenir

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

indexPathsForVisibleItems peut fonctionner dans la plupart des situations, mais parfois, il retourne un tableau avec plus d'un chemin d'index et il peut être difficile de déterminer 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)
140
Anthony

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)

    }

Swift 3 & Swift 4 :

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)
}
64
Sam Bing

Par souci d'exhaustivité, c'est la méthode qui a finalement fonctionné pour moi. C'était une combinaison des méthodes de @Anthony & @ 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);
}
17
Vincil Bishop

Il sera probablement préférable d'utiliser les méthodes UICollectionViewDelegate: (Swift 3)

// Called before the cell is displayed    
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    print(indexPath.row)
}

// Called when the cell is displayed
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    print(indexPath.row)
}
8
Mr Stanev

Je veux juste ajouter pour les autres: Pour une raison quelconque, je n’ai pas obtenu la cellule visible par l’utilisateur lorsque je faisais défiler jusqu’à la cellule previous dans collectionView avec pagingEnabled.

Donc, j'insère le code à l'intérieur de dispatch_async pour lui donner un peu d '"air" .__ et cela fonctionne pour moi.

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    dispatch_async(dispatch_get_main_queue(), ^{
            UICollectionViewCell * visibleCell= [[self.collectionView visibleCells] objectAtIndex:0];


            [visibleCell doSomthing];
        });
}
8
user1105951

Pour Swift 3.0

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let visibleRect = CGRect(Origin: colView.contentOffset, size: colView.bounds.size)
    let visiblePoint = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
    let indexPath = colView.indexPathForItem(at: visiblePoint)
}
7
Hiren Panchal

Swift 3.0

La solution la plus simple qui vous donnera indexPath pour les cellules visibles.

yourCollectionView.indexPathsForVisibleItems 

retournera le tableau de indexpath.

Prenez juste le premier objet du tableau comme ceci.

yourCollectionView.indexPathsForVisibleItems.first

Je suppose que cela devrait également bien fonctionner avec Objective - C.

5
Anil Kukadeja

Indice de cellule visible actuellement UICollectionView: Swift 3

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

     return nil
}
4
Mihail Salari

Vous pouvez utiliser scrollViewDidEndDecelerating: pour cela

//@property (strong, nonatomic) IBOutlet UICollectionView *collectionView;

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

        for (UICollectionViewCell *cell in [self.collectionView visibleCells]) {
            NSIndexPath *indexPath = [self.collectionView indexPathForCell:cell];
            NSUInteger lastIndex = [indexPath indexAtPosition:[indexPath length] - 1];
            NSLog(@"visible cell value %d",lastIndex);
        }

    }
2
raaz

convertir la réponse de @ Anthony en Swift 3.0 a parfaitement fonctionné pour moi:

func scrollViewDidScroll(_ scrollView: UIScrollView) {

    var visibleRect = CGRect()
    visibleRect.Origin = yourCollectionView.contentOffset
    visibleRect.size = yourCollectionView.bounds.size
    let visiblePoint = CGPoint(x: CGFloat(visibleRect.midX), y: CGFloat(visibleRect.midY))
    let visibleIndexPath: IndexPath? = yourCollectionView.indexPathForItem(at: visiblePoint)
    print("Visible cell's index is : \(visibleIndexPath?.row)!")
}
1
Nilesh Pol

Vérifiez également cet extrait

let isCellVisible = collectionView.visibleCells.map { collectionView.indexPath(for: $0) }.contains(inspectingIndexPath)
0
Nik Kov

C'est une vieille question mais dans mon cas ...

- (void) scrollViewWillBeginDragging:(UIScrollView *)scrollView {

    _m_offsetIdx = [m_cv indexPathForCell:m_cv.visibleCells.firstObject].row;
}

- (void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    _m_offsetIdx = [m_cv indexPathForCell:m_cv.visibleCells.lastObject].row;
}
0
Hwangho Kim