Как центрировать UICollectionView, когда он прослушивается?

У меня есть UICollectionView, и на нем есть много UICollectionViewCells. Я хочу прокрутить ячейку до центра UICollectionView, когда она нажата. Меня беспокоит, что даже если я нажимаю последнюю или верхнюю ячейку, она должна перемещаться в центр представления коллекции.

Я попытался установить contentInsets и смещения, но они, похоже, не работают. Я думаю, мне придется изменить размер содержимого при выборе и изменить его на оригинал, когда начнется прокрутка.

Ответ 1

Настройка contentInsets должен дать некоторое дополнительное пространство вокруг первой и последней ячеек:

CGFloat collectionViewHeight = CGRectGetHeight(collectionView.bounds);
[collectionView
  setContentInset:
   UIEdgeInsetsMake(collectionViewHeight/2, 0, collectionViewHeight/2, 0) ];
  // nb, those are top-left-bottom-right

После вызова:

[collectionView scrollToItemAtIndexPath:selectedItemPath
    atScrollPosition:UICollectionViewScrollPositionCenteredVertically
    animated:YES];

Важно пройти правильную позицию прокрутки: UICollectionViewScrollPositionCenteredVertically

Это должно быть правильно обработано.

ИЗМЕНИТЬ

Это действительно странно, но после установки метода UIEdgeInsets в метод просмотра scrollToItemAtIndexPath не работает должным образом, поэтому я делаю некоторые изменения:

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
    CGFloat collectionViewHeight = CGRectGetHeight(self.collectionView.frame);
    [collectionView setContentInset:UIEdgeInsetsMake(collectionViewHeight / 2, 0, collectionViewHeight / 2, 0)];

    UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
    CGPoint offset = CGPointMake(0,  cell.center.y - collectionViewHeight / 2);
    [collectionView setContentOffset:offset animated:YES];
}

он отлично работает для меня.

Ответ 2

Похоже, что эта ошибка вызвана плохим взаимодействием между прокруткой contentInset и UICollectionViewFlowLayout. В моем тестировании установка layout.sectionInset, а не collectionView.contentInset устранила проблему.

Основываясь на принятом ответе выше, я бы устранил обходной путь и изменил:

[collectionView setContentInset:UIEdgeInsetsMake(collectionViewHeight / 2, 0, collectionViewHeight / 2, 0)];

к

[layout setSectionInset:UIEdgeInsetsMake(collectionViewHeight / 2, 0, collectionViewHeight / 2, 0)];

Ответ 3

Вы можете использовать метод scrollToItemAtIndexPath, чтобы поместить выбранную (постукиваемую) ячейку в центральную позицию в UICollectionView

[collectionView scrollToItemAtIndexPath:indexPath
                       atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally
                               animated:true];

Вы можете использовать UICollectionViewScrollPositionCenteredVertically для вертикально-центрированного положения

Ответ 4

Swift 3 для экрана прокрутки и центрирования, чтобы сделать видимый элемент видимым:

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
  collectionView.scrollToItem(at: indexPath, at: .centeredVertically, animated: true)
}

Это не добавляет вставки над или под collectionView!