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
???
Ответы
Ответ 1
Метод [collectionView visibleCells] предоставляет вам все видимые массивы visibleCells. Используйте его, когда хотите получить
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
for (UICollectionViewCell *cell in [self.mainImageCollection visibleCells]) {
NSIndexPath *indexPath = [self.mainImageCollection indexPathForCell:cell];
NSLog(@"%@",indexPath);
}
}
Ответ 2
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];
Это особенно хорошо работает, когда каждый элемент в представлении коллекции занимает весь экран.
Ответ 3
Рабочие ответы, объединенные в 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 и 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)
}
Ответ 4
Для полноты, это метод, который в конечном итоге работает для меня. Это была комбинация методов @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);
}
Ответ 5
Просто хочу добавить для других:
по какой-то причине я не получил ячейку, которая была видна пользователю, когда я прокручивал предыдущую ячейку в коллекцииView с помощью pagingEnabled.
Итак, я вставляю код внутри dispatch_async, чтобы дать ему некоторый "воздух",
и это работает для меня.
-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
dispatch_async(dispatch_get_main_queue(), ^{
UICollectionViewCell * visibleCell= [[self.collectionView visibleCells] objectAtIndex:0];
[visibleCell doSomthing];
});
}
Ответ 6
Скорее всего, лучше использовать методы 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)
}
Ответ 7
Для 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)
}
Ответ 8
Вы можете использовать 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);
}
}
Ответ 9
Swift 3.0
Простейшее решение, которое даст вам indexPath для видимых ячеек.
yourCollectionView.indexPathsForVisibleItems
вернет массив указательного пути.
Просто возьмите первый объект из массива, как это.
yourCollectionView.indexPathsForVisibleItems.first
Я предполагаю, что он тоже отлично работает с Objective-C.
Ответ 10
UICollectionView текущий видимый индекс ячейки: Swift 3
var visibleCurrentCell: IndexPath? {
for cell in self.collectionView.visibleCells {
let indexPath = self.collectionView.indexPath(for: cell)
return indexPath
}
return nil
}
Ответ 11
Это старый вопрос, но в моем случае...
- (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
преобразование @Ответ Энтони на 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 index is : \(visibleIndexPath?.row)!")
}
Ответ 13
попробуйте это, он работает. (в приведенном ниже примере я имею, например, 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
}
}