Текущий видимый индекс ячейки UICollectionView
я использую UICollectionView
первый раз в моем приложении для iPad.
Я установил UICollectionView
такой, что его размер и размер ячейки одинаковы, означает, что только одна ячейка отображается одновременно.
: Теперь, когда пользователь прокручивает UICollectionView, мне нужно знать, какая ячейка видна, я должен обновить другие элементы пользовательского интерфейса при изменении. Я не нашел никакого метода делегата для этого. Как я могу этого достичь?
код:
[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
???
14 ответов:
метод [collectionView visibleCells] дает вам все visibleCells массив, который вы хотите. Используйте его, когда вы хотите сделать
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{ for (UICollectionViewCell *cell in [self.mainImageCollection visibleCells]) { NSIndexPath *indexPath = [self.mainImageCollection indexPathForCell:cell]; NSLog(@"%@",indexPath); } }
indexPathsForVisibleItems
может работать для большинства ситуаций, но иногда он возвращает массив с более чем одним путем индекса, и это может быть сложно выяснить, что вы хотите. В таких ситуациях вы можете сделать что-то вроде этого: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];
Это особенно хорошо работает, когда каждый элемент в коллекции занимает весь экран.
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)
Рабочие Ответы Объединены В 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) }
для полноты картины, это метод, который в конечном итоге работает для меня. Это была комбинация методов @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]; }); }
Для 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) }
вероятно, лучше всего использовать методы 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
простое решение, которое даст вам indexPath для видимых ячеек..
yourCollectionView.indexPathsForVisibleItems
вернет массив indexpath.
просто возьмите первый объект из массива, как это.
yourCollectionView.indexPathsForVisibleItems.first
Я думаю, что он должен отлично работать с Objective - C.
можно использовать
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 visibleCurrentCellIndexPath: IndexPath? { for cell in self.collectionView.visibleCells { let indexPath = self.collectionView.indexPath(for: cell) return indexPath } return nil }
преобразование ответа @Anthony в 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)!") }
Это старый вопрос, но в моем случае...
- (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; }
также проверьте этот фрагмент
let isCellVisible = collectionView.visibleCells.map { collectionView.indexPath(for: ) }.contains(inspectingIndexPath)
попробуйте это, это работает. (в приведенном ниже примере у меня есть 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 } }