webentwicklung-frage-antwort-db.com.de

UICollectionView aktueller sichtbarer Zellenindex

Ich verwende UICollectionView zum ersten Mal in meiner iPad-Anwendung . Ich habe UICollectionView so eingestellt, dass Größe und Zellengröße gleich sind, dh nur eine Zelle wird gleichzeitig angezeigt.

Problem: Wenn der Benutzer jetzt UICollectionView scrollt, muss ich wissen, welche Zelle sichtbar ist. Ich muss andere Benutzeroberflächenelemente bei Änderung aktualisieren. Ich habe keine Delegatmethode dafür gefunden. Wie kann ich das erreichen?

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];

Was ich versucht habe:

Da UICollectionView mit UIScrollView übereinstimmt, bekam ich, wenn der Benutzer-Scroll mit der UIScrollViewDelegate-Methode endet

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView

Aber innerhalb der oben genannten Funktion, wie kann ich den aktuellen sichtbaren Zellenindex von UICollectionView bekommen ???

87
Irfan DANISH

Die Methode [collectionView visibleCells] liefert Ihnen alle Array von visibleCells, die Sie möchten. Verwenden Sie es, wenn Sie möchten

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

indexPathsForVisibleItems kann in den meisten Situationen funktionieren, aber manchmal gibt es ein Array mit mehr als einem Indexpfad zurück. In solchen Situationen können Sie so etwas tun:

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];

Dies funktioniert besonders gut, wenn jedes Element in Ihrer Sammlungsansicht den gesamten Bildschirm einnimmt. 

Swift-Version  

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

Arbeitsantworten in Swift 2.2 kombiniert:

 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

Der Vollständigkeit halber ist dies die Methode, die für mich gelaufen ist. Es war eine Kombination der Methoden von @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

UICollectionViewDelegate-Methoden werden wahrscheinlich am besten verwendet: (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

Ich möchte nur für andere hinzufügen: Aus irgendeinem Grund habe ich nicht die Zelle erhalten, die für den Benutzer sichtbar war, als ich zu previous cell in collectionView mit pagingEnabled blätterte.

Also füge ich den Code in dispatch_async ein, um ein wenig "air" Zu geben, und das funktioniert für mich.

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


            [visibleCell doSomthing];
        });
}
8
user1105951

Für 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

Einfachste Lösung, mit der Sie indexPath für sichtbare Zellen erhalten.

yourCollectionView.indexPathsForVisibleItems 

gibt das Array von Indexpfad zurück.

Nehmen Sie einfach das erste Objekt aus dem Array wie folgt.

yourCollectionView.indexPathsForVisibleItems.first

Ich denke, es sollte auch mit Objective-C gut funktionieren.

5
Anil Kukadeja

UICollectionView aktueller sichtbarer Zellenindex: 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

Sie können scrollViewDidEndDecelerating: dafür verwenden

//@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

@ Anthony's Antwort in Swift 3.0 umwandeln hat für mich perfekt funktioniert:

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

Überprüfen Sie auch dieses Snippet

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

Das ist eine alte Frage, aber in meinem Fall ...

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