UICollectionView current visible cell index

匿名 (未验证) 提交于 2019-12-03 02:38:01

问题:

I am using UICollectionView first time in my iPad application. I have set UICollectionView such that its size and cell size is same, means only once cell is displayed at a time.

Problem: Now when user scroll UICollectionView I need to know which cell is visible I have to update other UI elements on change. I didn't find any delegate method for this. How can I achieve this?

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 have tried:

As UICollectionView Conforms to UIScrollView, I got when user scroll ends with UIScrollViewDelegate method

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 

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

回答1:

The method [collectionView visibleCells] give you all visibleCells array you want. Use it when you want to get

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


回答2:

indexPathsForVisibleItems might work for most situations, but sometimes it returns an array with more than one index path and it can be tricky figuring out the one you want. In those 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 each item in your collection view takes up the whole screen.



回答3:

Working Answers Combined 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)          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)      let visibleIndexPath: IndexPath = collectionView.indexPathForItem(at: visiblePoint)       guard let indexPath = visibleIndexPath else { return }      print(indexPath) } 


回答4:

For completeness sake, this is the method that ended up working for me. It was a combination of @Anthony & @iAn's 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); } 


回答5:

Just want to add for others : for some reason, I didnt not get the cell that was visible to the user when I was scrolling to previous cell in collectionView with pagingEnabled.

So I insert 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];         }); } 


回答6:

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


回答7:

It will probably be best to use 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) } 


回答8:

Swift 3.0

Simplest solution which will give you indexPath for visible cells..

yourCollectionView.indexPathsForVisibleItems  

will return the array of indexpath.

Just take the first object from array like this.

yourCollectionView.indexPathsForVisibleItems.first 

I guess it should work fine with Objective - C as well.



回答9:

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


回答10:

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 } 


回答11:

This is 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; } 


回答12:

converting @Anthony's answer to Swift 3.0 worked perfectly 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's index is : \(visibleIndexPath?.row)!") } 


回答13:

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

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


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!