UICollectionView当前可见的单元格索引

我在我的iPad应用程序中第一次使用UICollectionView 。 我设置了UICollectionView ,使其大小和单元大小相同,意味着一次只显示一个单元格。

问题:现在当用户滚动UICollectionView我需要知道哪个单元格可见,我必须更新其他UI元素的变化。 我没有find任何代表方法。 我怎样才能做到这一点?

码:

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

我曾经尝试过:

由于UICollectionView符合UIScrollView ,当用户滚动以UIScrollViewDelegate方法结束时

 -(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 

但是上面的函数里面怎么能得到UICollectionView当前可见单元UICollectionView

方法[collectionView visibleCells]为你提供所有visibleCells数组。 当你想要的时候使用它

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

indexPathsForVisibleItems可能适用于大多数情况,但有时它会返回一个包含多个索引path的数组,并且可能很难找出您想要的。 在这些情况下,你可以做这样的事情:

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

当您的collections视图中的每个项目占据整个屏幕时,这种工作效果特别好。

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

 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) } 

为了完整起见,这是最终为我工作的方法。 这是@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); } 

只是想为其他人添加:出于某种原因,我没有得到用户可见的单元格,当我滚动到collectionView中的前一个单元与pagingEnabled。

所以我在dispatch_async中插入代码给它一些“空气”,这对我很有用。

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

最好使用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) } 

对于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) } 

您可以使用scrollViewDidEndDecelerating :为此

 //@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); } } 

UICollectionView当前可见的单元格索引:Swift 3

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

Swift 3.0

最简单的解决scheme,它将为您提供可见单元格的indexPath ..

 yourCollectionView.indexPathsForVisibleItems 

将返回indexpath的数组。

就像这样从数组中获取第一个对象。

 yourCollectionView.indexPathsForVisibleItems.first 

我想这应该与Objective-C一起正常工作。

这是个老问题,但就我而言…

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

转换@安东尼的答案Swift 3.0完美的为我工作:

 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)!") } 

试试这个,它的工作。 (在下面的例子中,我有3个单元格)。

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