UICollectionView current visible cell index

I am using UICollectionView first time in my iPad application. I set the UICollectionView so that the cell size and size are the same, which means the cell is displayed immediately.

Problem: Now that the user scrolls through the UICollectionView, I need to know which cell is visible, I need to update other user interface elements when changing. For this, I did not find any delegate method. How can I achieve this?

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

What I tried:

How UICollectionView Matches UIScrollView I got when custom scrolling ends using the UIScrollViewDelegate method

 -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 

But inside the function above, how can I get the current visible index of a UICollectionView cell ???

+68
ios objective-c ipad uicollectionview
Sep 06 '13 at 4:30
source share
13 answers

The [collectionView visibleCells] method provides you with all visible arrays of visibleCells. Use it when you want to receive

 - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ for (UICollectionViewCell *cell in [self.mainImageCollection visibleCells]) { NSIndexPath *indexPath = [self.mainImageCollection indexPathForCell:cell]; NSLog(@"%@",indexPath); } } 
+99
Sep 06 '13 at 4:59
source share

indexPathsForVisibleItems can work in most situations, but sometimes it returns an array with more than one index path, and it can be difficult to determine what you want. In such situations, you can do something like this:

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

This works especially well when every item in the collection view is full screen.

+102
Jun 24 '14 at 21:28
source share

Working answers integrated in 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)! print(visibleIndexPath) } 

Swift 3 and 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) let visibleIndexPath: IndexPath = collectionView.indexPathForItem(at: visiblePoint)! print(visibleIndexPath) } 
+31
Apr 11 '16 at 12:44 on
source share

For completeness, this is the method that ultimately works for me. It was a combination of @Anthony and @iAn methods.

 - (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); } 
+15
Sep 18 '14 at
source share

Just want to add for others: for some reason, I didn’t get the cell that was visible to the user when I scroll through the previous cell in the View collection using pagingEnabled.

So, I embed the code inside dispatch_async to give it some “air”, and this works for me.

 -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { dispatch_async(dispatch_get_main_queue(), ^{ UICollectionViewCell * visibleCell= [[self.collectionView visibleCells] objectAtIndex:0]; [visibleCell doSomthing]; }); } 
+7
Mar 21 '15 at 21:54
source share

Most likely, it is better to use the UICollectionViewDelegate methods: (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) } 
+6
Jun 20 '17 at 14:08
source share

For 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) } 
+5
Jan 28 '17 at 12:23
source share

You can use scrollViewDidEndDecelerating : for this

 //@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
Oct 15 '14 at 13:28
source share

Swift 3.0

The simplest solution that will give you indexPath for visible cells.

 yourCollectionView.indexPathsForVisibleItems 

will return an array of the pointer path.

Just take the first object from an array like this.

 yourCollectionView.indexPathsForVisibleItems.first 

I guess it works fine with Objective-C too.

+2
May 29 '17 at 5:05 a.m.
source share

UICollectionView current visible cell index: Swift 3

 var visibleCurrentCell: IndexPath? { for cell in self.collectionView.visibleCells { let indexPath = self.collectionView.indexPath(for: cell) return indexPath } return nil } 
+1
Nov 24 '16 at 12:26
source share

This is an old question, but in my case ...

 - (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
May 23 '16 at 2:00
source share

conversion @ Anthony's answer on Swift 3.0 worked fine for me:

 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 index is : \(visibleIndexPath?.row)!") } 
0
May 10 '17 at 7:08 a.m.
source share

try this, it works. (in the example below, I have, for example, 3 cells.)

  func scrollViewDidEndDecelerating(scrollView: UIScrollView) { let visibleRect = CGRect(origin: self.collectionView.contentOffset, size: self.collectionView.bounds.size) let visiblePoint = CGPointMake(CGRectGetMidX(visibleRect), CGRectGetMidY(visibleRect)) let visibleIndexPath = self.collectionView.indexPathForItemAtPoint(visiblePoint) if let v = visibleIndexPath { switch v.item { case 0: setImageDescription() break case 1: setImageConditions() break case 2: setImageResults() break default: break } } 
-one
Nov 22 '16 at 5:21
source share



All Articles